@@ -35,3 +35,9 @@ Support requests in issues on this repository will be closed on sight.
## Contributing to WooCommerce
If you have a patch or have stumbled upon an issue with WooCommerce core, you can contribute this back to the code. Please read our [contributor guidelines](https://github.com/woocommerce/woocommerce/blob/trunk/.github/CONTRIBUTING.md) for more information how you can do this.
+
+
diff --git a/assets/css/twenty-twenty-one.scss b/assets/css/twenty-twenty-one.scss
index 1ddfb83a5dc..3091ae71eb2 100644
--- a/assets/css/twenty-twenty-one.scss
+++ b/assets/css/twenty-twenty-one.scss
@@ -348,6 +348,12 @@ a.button {
.woocommerce,
.woocommerce-page {
+ &.is-dark-theme {
+ .select2-dropdown {
+ color: var(--global--color-dark-gray);
+ }
+ }
+
table.shop_table {
td,
@@ -385,6 +391,7 @@ ul.products {
.woocommerce-loop-product__link {
display: block;
text-decoration: none;
+ position: relative;
}
.woocommerce-loop-product__title {
@@ -1311,6 +1318,30 @@ a.reset_variations {
}
}
+ &.woocommerce-lost-password {
+ .woocommerce {
+
+ max-width: var(--responsive--alignwide-width) !important;
+ padding: 0 !important;
+ flex-wrap: wrap;
+
+ .woocommerce-notices-wrapper {
+ flex: 1 0 100%;
+ }
+
+ .woocommerce-ResetPassword {
+
+ .woocommerce-form-row--first {
+ float: none;
+ }
+
+ #user_login {
+ margin-bottom: 10px;
+ }
+ }
+ }
+ }
+
table.account-orders-table {
margin-top: 0;
border: 0;
@@ -1432,6 +1463,11 @@ a.reset_variations {
}
.woocommerce-cart {
+ table.woocommerce-cart-form__contents {
+ thead, tfoot {
+ text-align: left;
+ }
+ }
.post-inner {
padding-top: 0;
@@ -2122,6 +2158,10 @@ a.reset_variations {
.woocommerce-table--order-details {
margin-bottom: 2rem;
+
+ thead, tfoot {
+ text-align: left;
+ }
}
/**
diff --git a/assets/css/twenty-twenty.scss b/assets/css/twenty-twenty.scss
index ad8cdab03be..3610d94c0d4 100644
--- a/assets/css/twenty-twenty.scss
+++ b/assets/css/twenty-twenty.scss
@@ -2474,6 +2474,12 @@ a.reset_variations {
margin: 1.5rem 0;
}
}
+
+ .woocommerce-ResetPassword {
+ .woocommerce-form-row--first {
+ float: none;
+ }
+ }
}
/**
diff --git a/assets/images/mercadopago.png b/assets/images/mercadopago.png
new file mode 100644
index 00000000000..39a790e5bf4
Binary files /dev/null and b/assets/images/mercadopago.png differ
diff --git a/assets/js/admin/meta-boxes-product-variation.js b/assets/js/admin/meta-boxes-product-variation.js
index 55ac9327559..551ad33a114 100644
--- a/assets/js/admin/meta-boxes-product-variation.js
+++ b/assets/js/admin/meta-boxes-product-variation.js
@@ -763,6 +763,7 @@ jQuery( function( $ ) {
case 'variable_regular_price' :
case 'variable_sale_price' :
case 'variable_stock' :
+ case 'variable_low_stock_amount' :
case 'variable_weight' :
case 'variable_length' :
case 'variable_width' :
diff --git a/assets/js/admin/wc-enhanced-select.js b/assets/js/admin/wc-enhanced-select.js
index 4eac44f6371..843ce80640c 100644
--- a/assets/js/admin/wc-enhanced-select.js
+++ b/assets/js/admin/wc-enhanced-select.js
@@ -72,6 +72,49 @@ jQuery( function( $ ) {
$( this ).selectWoo( select2_args ).addClass( 'enhanced' );
});
+ function display_result( self, select2_args ) {
+ select2_args = $.extend( select2_args, getEnhancedSelectFormatString() );
+
+ $( self ).selectWoo( select2_args ).addClass( 'enhanced' );
+
+ if ( $( self ).data( 'sortable' ) ) {
+ var $select = $(self);
+ var $list = $( self ).next( '.select2-container' ).find( 'ul.select2-selection__rendered' );
+
+ $list.sortable({
+ placeholder : 'ui-state-highlight select2-selection__choice',
+ forcePlaceholderSize: true,
+ items : 'li:not(.select2-search__field)',
+ tolerance : 'pointer',
+ stop: function() {
+ $( $list.find( '.select2-selection__choice' ).get().reverse() ).each( function() {
+ var id = $( self ).data( 'data' ).id;
+ var option = $select.find( 'option[value="' + id + '"]' )[0];
+ $select.prepend( option );
+ } );
+ }
+ });
+ // Keep multiselects ordered alphabetically if they are not sortable.
+ } else if ( $( self ).prop( 'multiple' ) ) {
+ $( self ).on( 'change', function(){
+ var $children = $( self ).children();
+ $children.sort(function(a, b){
+ var atext = a.text.toLowerCase();
+ var btext = b.text.toLowerCase();
+
+ if ( atext > btext ) {
+ return 1;
+ }
+ if ( atext < btext ) {
+ return -1;
+ }
+ return 0;
+ });
+ $( self ).html( $children );
+ });
+ }
+ }
+
// Ajax product search box
$( ':input.wc-product-search' ).filter( ':not(.enhanced)' ).each( function() {
var select2_args = {
@@ -112,46 +155,48 @@ jQuery( function( $ ) {
}
};
- select2_args = $.extend( select2_args, getEnhancedSelectFormatString() );
+ display_result( this, select2_args );
+ });
+
+ // Ajax Page Search.
+ $( ':input.wc-page-search' ).filter( ':not(.enhanced)' ).each( function() {
+ var select2_args = {
+ allowClear: $( this ).data( 'allow_clear' ) ? true : false,
+ placeholder: $( this ).data( 'placeholder' ),
+ minimumInputLength: $( this ).data( 'minimum_input_length' ) ? $( this ).data( 'minimum_input_length' ) : '3',
+ escapeMarkup: function( m ) {
+ return m;
+ },
+ ajax: {
+ url: wc_enhanced_select_params.ajax_url,
+ dataType: 'json',
+ delay: 250,
+ data: function( params ) {
+ return {
+ term : params.term,
+ action : $( this ).data( 'action' ) || 'woocommerce_json_search_pages',
+ security : wc_enhanced_select_params.search_pages_nonce,
+ exclude : $( this ).data( 'exclude' ),
+ post_status : $( this ).data( 'post_status' ),
+ limit : $( this ).data( 'limit' ),
+ };
+ },
+ processResults: function( data ) {
+ var terms = [];
+ if ( data ) {
+ $.each( data, function( id, text ) {
+ terms.push( { id: id, text: text } );
+ } );
+ }
+ return {
+ results: terms
+ };
+ },
+ cache: true
+ }
+ };
$( this ).selectWoo( select2_args ).addClass( 'enhanced' );
-
- if ( $( this ).data( 'sortable' ) ) {
- var $select = $(this);
- var $list = $( this ).next( '.select2-container' ).find( 'ul.select2-selection__rendered' );
-
- $list.sortable({
- placeholder : 'ui-state-highlight select2-selection__choice',
- forcePlaceholderSize: true,
- items : 'li:not(.select2-search__field)',
- tolerance : 'pointer',
- stop: function() {
- $( $list.find( '.select2-selection__choice' ).get().reverse() ).each( function() {
- var id = $( this ).data( 'data' ).id;
- var option = $select.find( 'option[value="' + id + '"]' )[0];
- $select.prepend( option );
- } );
- }
- });
- // Keep multiselects ordered alphabetically if they are not sortable.
- } else if ( $( this ).prop( 'multiple' ) ) {
- $( this ).on( 'change', function(){
- var $children = $( this ).children();
- $children.sort(function(a, b){
- var atext = a.text.toLowerCase();
- var btext = b.text.toLowerCase();
-
- if ( atext > btext ) {
- return 1;
- }
- if ( atext < btext ) {
- return -1;
- }
- return 0;
- });
- $( this ).html( $children );
- });
- }
});
// Ajax customer search boxes
diff --git a/assets/js/admin/wc-shipping-zone-methods.js b/assets/js/admin/wc-shipping-zone-methods.js
index 08e4d097d0c..45d17f19d21 100644
--- a/assets/js/admin/wc-shipping-zone-methods.js
+++ b/assets/js/admin/wc-shipping-zone-methods.js
@@ -62,6 +62,9 @@
shippingMethod.trigger( 'change:methods' );
shippingMethod.changes = {};
shippingMethod.trigger( 'saved:methods' );
+
+ // Overrides the onbeforeunload callback added by settings.js.
+ window.onbeforeunload = null;
} else {
window.alert( data.strings.save_failed );
}
diff --git a/assets/js/frontend/cart.js b/assets/js/frontend/cart.js
index 622c8eb1437..cdee33f5d79 100644
--- a/assets/js/frontend/cart.js
+++ b/assets/js/frontend/cart.js
@@ -57,6 +57,28 @@ jQuery( function( $ ) {
$node.removeClass( 'processing' ).unblock();
};
+ /**
+ * Removes duplicate notices.
+ *
+ * @param {JQuery Object} notices
+ */
+ var remove_duplicate_notices = function( notices ) {
+ var seen = [];
+ var new_notices = notices;
+
+ notices.each( function( index ) {
+ var text = $( this ).text();
+
+ if ( 'undefined' === typeof seen[ text ] ) {
+ seen[ text ] = true;
+ } else {
+ new_notices.splice( index, 1 );
+ }
+ } );
+
+ return new_notices;
+ };
+
/**
* Update the .woocommerce div with a string of html.
*
@@ -67,7 +89,7 @@ jQuery( function( $ ) {
var $html = $.parseHTML( html_str );
var $new_form = $( '.woocommerce-cart-form', $html );
var $new_totals = $( '.cart_totals', $html );
- var $notices = $( '.woocommerce-error, .woocommerce-message, .woocommerce-info', $html );
+ var $notices = remove_duplicate_notices( $( '.woocommerce-error, .woocommerce-message, .woocommerce-info', $html ) );
// No form, cannot do this.
if ( $( '.woocommerce-cart-form' ).length === 0 ) {
@@ -180,6 +202,7 @@ jQuery( function( $ ) {
*/
toggle_shipping: function() {
$( '.shipping-calculator-form' ).slideToggle( 'slow' );
+ $( 'select.country_to_state, input.country_to_state' ).trigger( 'change' );
$( document.body ).trigger( 'country_to_state_changed' ); // Trigger select2 to load.
return false;
},
diff --git a/assets/js/frontend/checkout.js b/assets/js/frontend/checkout.js
index 597ef13e4f0..c7e5960df7f 100644
--- a/assets/js/frontend/checkout.js
+++ b/assets/js/frontend/checkout.js
@@ -525,7 +525,7 @@ jQuery( function( $ ) {
wc_checkout_form.detachUnloadEventsOnSubmit();
try {
- if ( 'success' === result.result && $form.triggerHandler( 'checkout_place_order_success' ) !== false ) {
+ if ( 'success' === result.result && $form.triggerHandler( 'checkout_place_order_success', result ) !== false ) {
if ( -1 === result.redirect.indexOf( 'https://' ) || -1 === result.redirect.indexOf( 'http://' ) ) {
window.location = result.redirect;
} else {
diff --git a/assets/js/frontend/country-select.js b/assets/js/frontend/country-select.js
index 0c003dd9e41..00e9d902682 100644
--- a/assets/js/frontend/country-select.js
+++ b/assets/js/frontend/country-select.js
@@ -55,8 +55,11 @@ jQuery( function( $ ) {
var wc_country_select_select2 = function() {
$( 'select.country_select:visible, select.state_select:visible' ).each( function() {
+ var $this = $( this );
+
var select2_args = $.extend({
- placeholder: $( this ).attr( 'data-placeholder' ) || $( this ).attr( 'placeholder' ) || '',
+ placeholder: $this.attr( 'data-placeholder' ) || $this.attr( 'placeholder' ) || '',
+ label: $this.attr( 'data-label' ) || null,
width: '100%'
}, getEnhancedSelectFormatString() );
diff --git a/assets/js/select2/select2.full.js b/assets/js/select2/select2.full.js
index e750834ef5d..49cb11ee692 100644
--- a/assets/js/select2/select2.full.js
+++ b/assets/js/select2/select2.full.js
@@ -1,27 +1,41 @@
/*!
- * Select2 4.0.3
- * https://select2.github.io
+ * SelectWoo 1.0.9
+ * https://github.com/woocommerce/selectWoo
*
* Released under the MIT license
- * https://github.com/select2/select2/blob/master/LICENSE.md
+ * https://github.com/woocommerce/selectWoo/blob/master/LICENSE.md
*/
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
- } else if (typeof exports === 'object') {
+ } else if (typeof module === 'object' && module.exports) {
// Node/CommonJS
- factory(require('jquery'));
+ module.exports = function (root, jQuery) {
+ if (jQuery === undefined) {
+ // require('jQuery') returns a factory that requires window to
+ // build a jQuery instance, we normalize how we use modules
+ // that require this pattern but the window provided is a noop
+ // if it's defined (how jquery works)
+ if (typeof window !== 'undefined') {
+ jQuery = require('jquery');
+ }
+ else {
+ jQuery = require('jquery')(root);
+ }
+ }
+ factory(jQuery);
+ return jQuery;
+ };
} else {
// Browser globals
factory(jQuery);
}
-}(function (jQuery) {
+} (function (jQuery) {
// This is needed so we can catch the AMD loader configuration and use it
// The inner file should be wrapped (by `banner.start.js`) in a function that
// returns the AMD loader references.
- var S2 =
-(function () {
+ var S2 =(function () {
// Restore the Select2 AMD loader so it can be used
// Needed mostly in the language files, where the loader is not inserted
if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) {
@@ -30,13 +44,11 @@
var S2;(function () { if (!S2 || !S2.requirejs) {
if (!S2) { S2 = {}; } else { require = S2; }
/**
- * @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
- * Available via the MIT or new BSD license.
- * see: http://github.com/jrburke/almond for details
+ * @license almond 0.3.3 Copyright jQuery Foundation and other contributors.
+ * Released under MIT license, http://github.com/requirejs/almond/LICENSE
*/
//Going sloppy to avoid 'use strict' string cost, but strict practices should
//be followed.
-/*jslint sloppy: true */
/*global setTimeout: false */
var requirejs, require, define;
@@ -64,60 +76,58 @@ var requirejs, require, define;
*/
function normalize(name, baseName) {
var nameParts, nameSegment, mapValue, foundMap, lastIndex,
- foundI, foundStarMap, starI, i, j, part,
+ foundI, foundStarMap, starI, i, j, part, normalizedBaseParts,
baseParts = baseName && baseName.split("/"),
map = config.map,
starMap = (map && map['*']) || {};
//Adjust any relative paths.
- if (name && name.charAt(0) === ".") {
- //If have a base name, try to normalize against it,
- //otherwise, assume it is a top-level require that will
- //be relative to baseUrl in the end.
- if (baseName) {
- name = name.split('/');
- lastIndex = name.length - 1;
+ if (name) {
+ name = name.split('/');
+ lastIndex = name.length - 1;
- // Node .js allowance:
- if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
- name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
- }
+ // If wanting node ID compatibility, strip .js from end
+ // of IDs. Have to do this here, and not in nameToUrl
+ // because node allows either .js or non .js to map
+ // to same file.
+ if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
+ name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
+ }
- //Lop off the last part of baseParts, so that . matches the
- //"directory" and not name of the baseName's module. For instance,
- //baseName of "one/two/three", maps to "one/two/three.js", but we
- //want the directory, "one/two" for this normalization.
- name = baseParts.slice(0, baseParts.length - 1).concat(name);
+ // Starts with a '.' so need the baseName
+ if (name[0].charAt(0) === '.' && baseParts) {
+ //Convert baseName to array, and lop off the last part,
+ //so that . matches that 'directory' and not name of the baseName's
+ //module. For instance, baseName of 'one/two/three', maps to
+ //'one/two/three.js', but we want the directory, 'one/two' for
+ //this normalization.
+ normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
+ name = normalizedBaseParts.concat(name);
+ }
- //start trimDots
- for (i = 0; i < name.length; i += 1) {
- part = name[i];
- if (part === ".") {
- name.splice(i, 1);
- i -= 1;
- } else if (part === "..") {
- if (i === 1 && (name[2] === '..' || name[0] === '..')) {
- //End of the line. Keep at least one non-dot
- //path segment at the front so it can be mapped
- //correctly to disk. Otherwise, there is likely
- //no path mapping for a path starting with '..'.
- //This can still fail, but catches the most reasonable
- //uses of ..
- break;
- } else if (i > 0) {
- name.splice(i - 1, 2);
- i -= 2;
- }
+ //start trimDots
+ for (i = 0; i < name.length; i++) {
+ part = name[i];
+ if (part === '.') {
+ name.splice(i, 1);
+ i -= 1;
+ } else if (part === '..') {
+ // If at the start, or previous value is still ..,
+ // keep them so that when converted to a path it may
+ // still work when converted to a path, even though
+ // as an ID it is less than ideal. In larger point
+ // releases, may be better to just kick out an error.
+ if (i === 0 || (i === 1 && name[2] === '..') || name[i - 1] === '..') {
+ continue;
+ } else if (i > 0) {
+ name.splice(i - 1, 2);
+ i -= 2;
}
}
- //end trimDots
-
- name = name.join("/");
- } else if (name.indexOf('./') === 0) {
- // No baseName, so this is ID is resolved relative
- // to baseUrl, pull off the leading dot.
- name = name.substring(2);
}
+ //end trimDots
+
+ name = name.join('/');
}
//Apply map config if available.
@@ -230,32 +240,39 @@ var requirejs, require, define;
return [prefix, name];
}
+ //Creates a parts array for a relName where first part is plugin ID,
+ //second part is resource ID. Assumes relName has already been normalized.
+ function makeRelParts(relName) {
+ return relName ? splitPrefix(relName) : [];
+ }
+
/**
* Makes a name map, normalizing the name, and using a plugin
* for normalization if necessary. Grabs a ref to plugin
* too, as an optimization.
*/
- makeMap = function (name, relName) {
+ makeMap = function (name, relParts) {
var plugin,
parts = splitPrefix(name),
- prefix = parts[0];
+ prefix = parts[0],
+ relResourceName = relParts[1];
name = parts[1];
if (prefix) {
- prefix = normalize(prefix, relName);
+ prefix = normalize(prefix, relResourceName);
plugin = callDep(prefix);
}
//Normalize according
if (prefix) {
if (plugin && plugin.normalize) {
- name = plugin.normalize(name, makeNormalize(relName));
+ name = plugin.normalize(name, makeNormalize(relResourceName));
} else {
- name = normalize(name, relName);
+ name = normalize(name, relResourceName);
}
} else {
- name = normalize(name, relName);
+ name = normalize(name, relResourceName);
parts = splitPrefix(name);
prefix = parts[0];
name = parts[1];
@@ -302,13 +319,14 @@ var requirejs, require, define;
};
main = function (name, deps, callback, relName) {
- var cjsModule, depName, ret, map, i,
+ var cjsModule, depName, ret, map, i, relParts,
args = [],
callbackType = typeof callback,
usingExports;
//Use name if no relName
relName = relName || name;
+ relParts = makeRelParts(relName);
//Call the callback to define the module, if necessary.
if (callbackType === 'undefined' || callbackType === 'function') {
@@ -317,7 +335,7 @@ var requirejs, require, define;
//Default to [require, exports, module] if no deps
deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
for (i = 0; i < deps.length; i += 1) {
- map = makeMap(deps[i], relName);
+ map = makeMap(deps[i], relParts);
depName = map.f;
//Fast path CommonJS standard dependencies.
@@ -373,7 +391,7 @@ var requirejs, require, define;
//deps arg is the module name, and second arg (if passed)
//is just the relName.
//Normalize module name, if it contains . or ..
- return callDep(makeMap(deps, callback).f);
+ return callDep(makeMap(deps, makeRelParts(callback)).f);
} else if (!deps.splice) {
//deps is a config object, not an array.
config = deps;
@@ -737,6 +755,12 @@ S2.define('select2/utils',[
});
};
+ Utils.entityDecode = function (html) {
+ var txt = document.createElement('textarea');
+ txt.innerHTML = html;
+ return txt.value;
+ }
+
// Append an array of jQuery nodes to a given element.
Utils.appendMany = function ($element, $nodes) {
// jQuery 1.7.x does not support $.fn.append() with an array
@@ -754,6 +778,14 @@ S2.define('select2/utils',[
$element.append($nodes);
};
+ // Determine whether the browser is on a touchscreen device.
+ Utils.isTouchscreen = function() {
+ if ('undefined' === typeof Utils._isTouchscreenCache) {
+ Utils._isTouchscreenCache = 'ontouchstart' in document.documentElement;
+ }
+ return Utils._isTouchscreenCache;
+ }
+
return Utils;
});
@@ -773,7 +805,7 @@ S2.define('select2/results',[
Results.prototype.render = function () {
var $results = $(
- '
'
+ '
'
);
if (this.options.get('multiple')) {
@@ -796,7 +828,7 @@ S2.define('select2/results',[
this.hideLoading();
var $message = $(
- ''
);
@@ -858,9 +890,9 @@ S2.define('select2/results',[
Results.prototype.highlightFirstItem = function () {
var $options = this.$results
- .find('.select2-results__option[aria-selected]');
+ .find('.select2-results__option[data-selected]');
- var $selected = $options.filter('[aria-selected=true]');
+ var $selected = $options.filter('[data-selected=true]');
// Check if there are any selected options
if ($selected.length > 0) {
@@ -884,7 +916,7 @@ S2.define('select2/results',[
});
var $options = self.$results
- .find('.select2-results__option[aria-selected]');
+ .find('.select2-results__option[data-selected]');
$options.each(function () {
var $option = $(this);
@@ -896,9 +928,9 @@ S2.define('select2/results',[
if ((item.element != null && item.element.selected) ||
(item.element == null && $.inArray(id, selectedIds) > -1)) {
- $option.attr('aria-selected', 'true');
+ $option.attr('data-selected', 'true');
} else {
- $option.attr('aria-selected', 'false');
+ $option.attr('data-selected', 'false');
}
});
@@ -930,17 +962,18 @@ S2.define('select2/results',[
option.className = 'select2-results__option';
var attrs = {
- 'role': 'treeitem',
- 'aria-selected': 'false'
+ 'role': 'option',
+ 'data-selected': 'false',
+ 'tabindex': -1
};
if (data.disabled) {
- delete attrs['aria-selected'];
+ delete attrs['data-selected'];
attrs['aria-disabled'] = 'true';
}
if (data.id == null) {
- delete attrs['aria-selected'];
+ delete attrs['data-selected'];
}
if (data._resultId != null) {
@@ -952,9 +985,8 @@ S2.define('select2/results',[
}
if (data.children) {
- attrs.role = 'group';
attrs['aria-label'] = data.text;
- delete attrs['aria-selected'];
+ delete attrs['data-selected'];
}
for (var attr in attrs) {
@@ -971,6 +1003,7 @@ S2.define('select2/results',[
var $label = $(label);
this.template(data, label);
+ $label.attr('role', 'presentation');
var $children = [];
@@ -983,10 +1016,11 @@ S2.define('select2/results',[
}
var $childrenContainer = $('
', {
- 'class': 'select2-results__options select2-results__options--nested'
+ 'class': 'select2-results__options select2-results__options--nested',
+ 'role': 'listbox'
});
-
$childrenContainer.append($children);
+ $option.attr('role', 'list');
$option.append(label);
$option.append($childrenContainer);
@@ -1082,7 +1116,7 @@ S2.define('select2/results',[
var data = $highlighted.data('data');
- if ($highlighted.attr('aria-selected') == 'true') {
+ if ($highlighted.attr('data-selected') == 'true') {
self.trigger('close', {});
} else {
self.trigger('select', {
@@ -1094,7 +1128,7 @@ S2.define('select2/results',[
container.on('results:previous', function () {
var $highlighted = self.getHighlightedResults();
- var $options = self.$results.find('[aria-selected]');
+ var $options = self.$results.find('[data-selected]');
var currentIndex = $options.index($highlighted);
@@ -1128,7 +1162,7 @@ S2.define('select2/results',[
container.on('results:next', function () {
var $highlighted = self.getHighlightedResults();
- var $options = self.$results.find('[aria-selected]');
+ var $options = self.$results.find('[data-selected]');
var currentIndex = $options.index($highlighted);
@@ -1156,7 +1190,8 @@ S2.define('select2/results',[
});
container.on('results:focus', function (params) {
- params.element.addClass('select2-results__option--highlighted');
+ params.element.addClass('select2-results__option--highlighted').attr('aria-selected', 'true');
+ self.$results.attr('aria-activedescendant', params.element.attr('id'));
});
container.on('results:message', function (params) {
@@ -1188,13 +1223,13 @@ S2.define('select2/results',[
});
}
- this.$results.on('mouseup', '.select2-results__option[aria-selected]',
+ this.$results.on('mouseup', '.select2-results__option[data-selected]',
function (evt) {
var $this = $(this);
var data = $this.data('data');
- if ($this.attr('aria-selected') === 'true') {
+ if ($this.attr('data-selected') === 'true') {
if (self.options.get('multiple')) {
self.trigger('unselect', {
originalEvent: evt,
@@ -1213,12 +1248,13 @@ S2.define('select2/results',[
});
});
- this.$results.on('mouseenter', '.select2-results__option[aria-selected]',
+ this.$results.on('mouseenter', '.select2-results__option[data-selected]',
function (evt) {
var data = $(this).data('data');
self.getHighlightedResults()
- .removeClass('select2-results__option--highlighted');
+ .removeClass('select2-results__option--highlighted')
+ .attr('aria-selected', 'false');
self.trigger('results:focus', {
data: data,
@@ -1245,7 +1281,7 @@ S2.define('select2/results',[
return;
}
- var $options = this.$results.find('[aria-selected]');
+ var $options = this.$results.find('[data-selected]');
var currentIndex = $options.index($highlighted);
@@ -1323,7 +1359,7 @@ S2.define('select2/selection/base',[
BaseSelection.prototype.render = function () {
var $selection = $(
- '' +
''
);
@@ -1349,6 +1385,7 @@ S2.define('select2/selection/base',[
var id = container.id + '-container';
var resultsId = container.id + '-results';
+ var searchHidden = this.options.get('minimumResultsForSearch') === Infinity;
this.container = container;
@@ -1390,7 +1427,11 @@ S2.define('select2/selection/base',[
self.$selection.removeAttr('aria-activedescendant');
self.$selection.removeAttr('aria-owns');
- self.$selection.focus();
+ // This needs to be delayed as the active element is the body when the
+ // key is pressed.
+ window.setTimeout(function () {
+ self.$selection.focus();
+ }, 1);
self._detachCloseHandler(container);
});
@@ -1440,8 +1481,14 @@ S2.define('select2/selection/base',[
}
var $element = $this.data('element');
-
$element.select2('close');
+
+ // Remove any focus when dropdown is closed by clicking outside the select area.
+ // Timeout of 1 required for close to finish wrapping up.
+ setTimeout(function(){
+ $this.find('*:focus').blur();
+ $target.focus();
+ }, 1);
});
});
};
@@ -1500,8 +1547,21 @@ S2.define('select2/selection/single',[
var id = container.id + '-container';
- this.$selection.find('.select2-selection__rendered').attr('id', id);
- this.$selection.attr('aria-labelledby', id);
+ this.$selection.find('.select2-selection__rendered')
+ .attr('id', id)
+ .attr('role', 'textbox')
+ .attr('aria-readonly', 'true');
+
+ var label = this.options.get( 'label' );
+
+ if ( typeof( label ) === 'string' ) {
+ this.$selection.attr( 'aria-label', label );
+ } else {
+ this.$selection.attr( 'aria-labelledby', id );
+ }
+
+ // This makes single non-search selects work in screen readers. If it causes problems elsewhere, remove.
+ this.$selection.attr('role', 'combobox');
this.$selection.on('mousedown', function (evt) {
// Only respond to left clicks
@@ -1518,6 +1578,13 @@ S2.define('select2/selection/single',[
// User focuses on the container
});
+ this.$selection.on('keydown', function (evt) {
+ // If user starts typing an alphanumeric key on the keyboard, open if not opened.
+ if (!container.isOpen() && evt.which >= 48 && evt.which <= 90) {
+ container.open();
+ }
+ });
+
this.$selection.on('blur', function (evt) {
// User exits the container
});
@@ -1557,9 +1624,9 @@ S2.define('select2/selection/single',[
var selection = data[0];
var $rendered = this.$selection.find('.select2-selection__rendered');
- var formatted = this.display(selection, $rendered);
+ var formatted = Utils.entityDecode(this.display(selection, $rendered));
- $rendered.empty().append(formatted);
+ $rendered.empty().text(formatted);
$rendered.prop('title', selection.title || selection.text);
};
@@ -1583,7 +1650,7 @@ S2.define('select2/selection/multiple',[
$selection.addClass('select2-selection--multiple');
$selection.html(
- '
'
+ '
'
);
return $selection;
@@ -1620,6 +1687,18 @@ S2.define('select2/selection/multiple',[
});
}
);
+
+ this.$selection.on('keydown', function (evt) {
+ // If user starts typing an alphanumeric key on the keyboard, open if not opened.
+ if (!container.isOpen() && evt.which >= 48 && evt.which <= 90) {
+ container.open();
+ }
+ });
+
+ // Focus on the search field when the container is focused instead of the main container.
+ container.on( 'focus', function(){
+ self.focusOnSearch();
+ });
};
MultipleSelection.prototype.clear = function () {
@@ -1636,7 +1715,7 @@ S2.define('select2/selection/multiple',[
MultipleSelection.prototype.selectionContainer = function () {
var $container = $(
'
' +
- '' +
+ '' +
'×' +
'' +
'
'
@@ -1645,6 +1724,24 @@ S2.define('select2/selection/multiple',[
return $container;
};
+ /**
+ * Focus on the search field instead of the main multiselect container.
+ */
+ MultipleSelection.prototype.focusOnSearch = function() {
+ var self = this;
+
+ if ('undefined' !== typeof self.$search) {
+ // Needs 1 ms delay because of other 1 ms setTimeouts when rendering.
+ setTimeout(function(){
+ // Prevent the dropdown opening again when focused from this.
+ // This gets reset automatically when focus is triggered.
+ self._keyUpPrevented = true;
+
+ self.$search.focus();
+ }, 1);
+ }
+ }
+
MultipleSelection.prototype.update = function (data) {
this.clear();
@@ -1658,9 +1755,14 @@ S2.define('select2/selection/multiple',[
var selection = data[d];
var $selection = this.selectionContainer();
+ var removeItemTag = $selection.html();
var formatted = this.display(selection, $selection);
+ if ('string' === typeof formatted) {
+ formatted = Utils.entityDecode(formatted.trim());
+ }
- $selection.append(formatted);
+ $selection.text(formatted);
+ $selection.prepend(removeItemTag);
$selection.prop('title', selection.title || selection.text);
$selection.data('data', selection);
@@ -1699,7 +1801,7 @@ S2.define('select2/selection/placeholder',[
Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
var $placeholder = this.selectionContainer();
- $placeholder.html(this.display(placeholder));
+ $placeholder.text(Utils.entityDecode(this.display(placeholder)));
$placeholder.addClass('select2-selection__placeholder')
.removeClass('select2-selection__choice');
@@ -1836,8 +1938,8 @@ S2.define('select2/selection/search',[
Search.prototype.render = function (decorated) {
var $search = $(
'
' +
- '' +
'
'
);
@@ -1854,16 +1956,19 @@ S2.define('select2/selection/search',[
Search.prototype.bind = function (decorated, container, $container) {
var self = this;
+ var resultsId = container.id + '-results';
decorated.call(this, container, $container);
container.on('open', function () {
+ self.$search.attr('aria-owns', resultsId);
self.$search.trigger('focus');
});
container.on('close', function () {
self.$search.val('');
self.$search.removeAttr('aria-activedescendant');
+ self.$search.removeAttr('aria-owns');
self.$search.trigger('focus');
});
@@ -1882,7 +1987,7 @@ S2.define('select2/selection/search',[
});
container.on('results:focus', function (params) {
- self.$search.attr('aria-activedescendant', params.id);
+ self.$search.attr('aria-activedescendant', params.data._resultId);
});
this.$selection.on('focusin', '.select2-search--inline', function (evt) {
@@ -1913,6 +2018,9 @@ S2.define('select2/selection/search',[
evt.preventDefault();
}
+ } else if (evt.which === KEYS.ENTER) {
+ container.open();
+ evt.preventDefault();
}
});
@@ -3004,8 +3112,15 @@ S2.define('select2/data/base',[
};
BaseAdapter.prototype.generateResultId = function (container, data) {
- var id = container.id + '-result-';
+ var id = '';
+ if (container != null) {
+ id += container.id
+ } else {
+ id += Utils.generateChars(4);
+ }
+
+ id += '-result-';
id += Utils.generateChars(4);
if (data.id != null) {
@@ -3191,7 +3306,7 @@ S2.define('select2/data/select',[
}
}
- if (data.id) {
+ if (data.id !== undefined) {
option.value = data.id;
}
@@ -3289,7 +3404,7 @@ S2.define('select2/data/select',[
item.text = item.text.toString();
}
- if (item._resultId == null && item.id && this.container != null) {
+ if (item._resultId == null && item.id) {
item._resultId = this.generateResultId(this.container, item);
}
@@ -3466,6 +3581,7 @@ S2.define('select2/data/ajax',[
}
callback(results);
+ self.container.focusOnActiveElement();
}, function () {
// Attempt to detect if a request was aborted
// Only works if the transport exposes a status property
@@ -3550,7 +3666,10 @@ S2.define('select2/data/tags',[
}, true)
);
- var checkText = option.text === params.term;
+ var optionText = (option.text || '').toUpperCase();
+ var paramsTerm = (params.term || '').toUpperCase();
+
+ var checkText = optionText === paramsTerm;
if (checkText || checkChildren) {
if (child) {
@@ -3887,9 +4006,9 @@ S2.define('select2/dropdown/search',[
var $search = $(
'' +
- '' +
+ '' +
''
);
@@ -3903,6 +4022,7 @@ S2.define('select2/dropdown/search',[
Search.prototype.bind = function (decorated, container, $container) {
var self = this;
+ var resultsId = container.id + '-results';
decorated.call(this, container, $container);
@@ -3926,7 +4046,7 @@ S2.define('select2/dropdown/search',[
container.on('open', function () {
self.$search.attr('tabindex', 0);
-
+ self.$search.attr('aria-owns', resultsId);
self.$search.focus();
window.setTimeout(function () {
@@ -3936,12 +4056,13 @@ S2.define('select2/dropdown/search',[
container.on('close', function () {
self.$search.attr('tabindex', -1);
-
+ self.$search.removeAttr('aria-activedescendant');
+ self.$search.removeAttr('aria-owns');
self.$search.val('');
});
container.on('focus', function () {
- if (container.isOpen()) {
+ if (!container.isOpen()) {
self.$search.focus();
}
});
@@ -3957,6 +4078,10 @@ S2.define('select2/dropdown/search',[
}
}
});
+
+ container.on('results:focus', function (params) {
+ self.$search.attr('aria-activedescendant', params.data._resultId);
+ });
};
Search.prototype.handleSearch = function (evt) {
@@ -4098,7 +4223,7 @@ S2.define('select2/dropdown/infiniteScroll',[
var $option = $(
''
+ 'role="option" aria-disabled="true">'
);
var message = this.options.get('translations').get('loadingMore');
@@ -5344,16 +5469,22 @@ S2.define('select2/core',[
});
});
- this.on('keypress', function (evt) {
- var key = evt.which;
+ this.on('open', function(){
+ // Focus on the active element when opening dropdown.
+ // Needs 1 ms delay because of other 1 ms setTimeouts when rendering.
+ setTimeout(function(){
+ self.focusOnActiveElement();
+ }, 1);
+ });
+ $(document).on('keydown', function (evt) {
+ var key = evt.which;
if (self.isOpen()) {
- if (key === KEYS.ESC || key === KEYS.TAB ||
- (key === KEYS.UP && evt.altKey)) {
+ if (key === KEYS.ESC || (key === KEYS.UP && evt.altKey)) {
self.close();
evt.preventDefault();
- } else if (key === KEYS.ENTER) {
+ } else if (key === KEYS.ENTER || key === KEYS.TAB) {
self.trigger('results:select', {});
evt.preventDefault();
@@ -5370,17 +5501,42 @@ S2.define('select2/core',[
evt.preventDefault();
}
- } else {
- if (key === KEYS.ENTER || key === KEYS.SPACE ||
- (key === KEYS.DOWN && evt.altKey)) {
- self.open();
+ var $searchField = self.$dropdown.find('.select2-search__field');
+ if (! $searchField.length) {
+ $searchField = self.$container.find('.select2-search__field');
+ }
+
+ // Move the focus to the selected element on keyboard navigation.
+ // Required for screen readers to work properly.
+ if (key === KEYS.DOWN || key === KEYS.UP) {
+ self.focusOnActiveElement();
+ } else {
+ // Focus on the search if user starts typing.
+ $searchField.focus();
+ // Focus back to active selection when finished typing.
+ // Small delay so typed character can be read by screen reader.
+ setTimeout(function(){
+ self.focusOnActiveElement();
+ }, 1000);
+ }
+ } else if (self.hasFocus()) {
+ if (key === KEYS.ENTER || key === KEYS.SPACE ||
+ key === KEYS.DOWN) {
+ self.open();
evt.preventDefault();
}
}
});
};
+ Select2.prototype.focusOnActiveElement = function () {
+ // Don't mess with the focus on touchscreens because it causes havoc with on-screen keyboards.
+ if (this.isOpen() && ! Utils.isTouchscreen()) {
+ this.$results.find('li.select2-results__option--highlighted').focus();
+ }
+ };
+
Select2.prototype._syncAttributes = function () {
this.options.set('disabled', this.$element.prop('disabled'));
@@ -6364,11 +6520,11 @@ S2.define('jquery.select2',[
'./select2/core',
'./select2/defaults'
], function ($, _, Select2, Defaults) {
- if ($.fn.select2 == null) {
+ if ($.fn.selectWoo == null) {
// All methods that should return the element
var thisMethods = ['open', 'close', 'destroy'];
- $.fn.select2 = function (options) {
+ $.fn.selectWoo = function (options) {
options = options || {};
if (typeof options === 'object') {
@@ -6408,10 +6564,17 @@ S2.define('jquery.select2',[
};
}
- if ($.fn.select2.defaults == null) {
- $.fn.select2.defaults = Defaults;
+ if ($.fn.select2 != null && $.fn.select2.defaults != null) {
+ $.fn.selectWoo.defaults = $.fn.select2.defaults;
}
+ if ($.fn.selectWoo.defaults == null) {
+ $.fn.selectWoo.defaults = Defaults;
+ }
+
+ // Also register selectWoo under select2 if select2 is not already present.
+ $.fn.select2 = $.fn.select2 || $.fn.selectWoo;
+
return Select2;
});
@@ -6430,6 +6593,7 @@ S2.define('jquery.select2',[
// This allows Select2 to use the internal loader outside of this file, such
// as in the language files.
jQuery.fn.select2.amd = S2;
+ jQuery.fn.selectWoo.amd = S2;
// Return the Select2 instance for anyone who is importing it.
return select2;
diff --git a/assets/js/select2/select2.js b/assets/js/select2/select2.js
index 13b84fadff6..3f27bbd4032 100644
--- a/assets/js/select2/select2.js
+++ b/assets/js/select2/select2.js
@@ -1,27 +1,41 @@
/*!
- * Select2 4.0.3
- * https://select2.github.io
+ * SelectWoo 1.0.9
+ * https://github.com/woocommerce/selectWoo
*
* Released under the MIT license
- * https://github.com/select2/select2/blob/master/LICENSE.md
+ * https://github.com/woocommerce/selectWoo/blob/master/LICENSE.md
*/
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
- } else if (typeof exports === 'object') {
+ } else if (typeof module === 'object' && module.exports) {
// Node/CommonJS
- factory(require('jquery'));
+ module.exports = function (root, jQuery) {
+ if (jQuery === undefined) {
+ // require('jQuery') returns a factory that requires window to
+ // build a jQuery instance, we normalize how we use modules
+ // that require this pattern but the window provided is a noop
+ // if it's defined (how jquery works)
+ if (typeof window !== 'undefined') {
+ jQuery = require('jquery');
+ }
+ else {
+ jQuery = require('jquery')(root);
+ }
+ }
+ factory(jQuery);
+ return jQuery;
+ };
} else {
// Browser globals
factory(jQuery);
}
-}(function (jQuery) {
+} (function (jQuery) {
// This is needed so we can catch the AMD loader configuration and use it
// The inner file should be wrapped (by `banner.start.js`) in a function that
// returns the AMD loader references.
- var S2 =
-(function () {
+ var S2 =(function () {
// Restore the Select2 AMD loader so it can be used
// Needed mostly in the language files, where the loader is not inserted
if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) {
@@ -30,13 +44,11 @@
var S2;(function () { if (!S2 || !S2.requirejs) {
if (!S2) { S2 = {}; } else { require = S2; }
/**
- * @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
- * Available via the MIT or new BSD license.
- * see: http://github.com/jrburke/almond for details
+ * @license almond 0.3.3 Copyright jQuery Foundation and other contributors.
+ * Released under MIT license, http://github.com/requirejs/almond/LICENSE
*/
//Going sloppy to avoid 'use strict' string cost, but strict practices should
//be followed.
-/*jslint sloppy: true */
/*global setTimeout: false */
var requirejs, require, define;
@@ -64,60 +76,58 @@ var requirejs, require, define;
*/
function normalize(name, baseName) {
var nameParts, nameSegment, mapValue, foundMap, lastIndex,
- foundI, foundStarMap, starI, i, j, part,
+ foundI, foundStarMap, starI, i, j, part, normalizedBaseParts,
baseParts = baseName && baseName.split("/"),
map = config.map,
starMap = (map && map['*']) || {};
//Adjust any relative paths.
- if (name && name.charAt(0) === ".") {
- //If have a base name, try to normalize against it,
- //otherwise, assume it is a top-level require that will
- //be relative to baseUrl in the end.
- if (baseName) {
- name = name.split('/');
- lastIndex = name.length - 1;
+ if (name) {
+ name = name.split('/');
+ lastIndex = name.length - 1;
- // Node .js allowance:
- if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
- name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
- }
+ // If wanting node ID compatibility, strip .js from end
+ // of IDs. Have to do this here, and not in nameToUrl
+ // because node allows either .js or non .js to map
+ // to same file.
+ if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
+ name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
+ }
- //Lop off the last part of baseParts, so that . matches the
- //"directory" and not name of the baseName's module. For instance,
- //baseName of "one/two/three", maps to "one/two/three.js", but we
- //want the directory, "one/two" for this normalization.
- name = baseParts.slice(0, baseParts.length - 1).concat(name);
+ // Starts with a '.' so need the baseName
+ if (name[0].charAt(0) === '.' && baseParts) {
+ //Convert baseName to array, and lop off the last part,
+ //so that . matches that 'directory' and not name of the baseName's
+ //module. For instance, baseName of 'one/two/three', maps to
+ //'one/two/three.js', but we want the directory, 'one/two' for
+ //this normalization.
+ normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
+ name = normalizedBaseParts.concat(name);
+ }
- //start trimDots
- for (i = 0; i < name.length; i += 1) {
- part = name[i];
- if (part === ".") {
- name.splice(i, 1);
- i -= 1;
- } else if (part === "..") {
- if (i === 1 && (name[2] === '..' || name[0] === '..')) {
- //End of the line. Keep at least one non-dot
- //path segment at the front so it can be mapped
- //correctly to disk. Otherwise, there is likely
- //no path mapping for a path starting with '..'.
- //This can still fail, but catches the most reasonable
- //uses of ..
- break;
- } else if (i > 0) {
- name.splice(i - 1, 2);
- i -= 2;
- }
+ //start trimDots
+ for (i = 0; i < name.length; i++) {
+ part = name[i];
+ if (part === '.') {
+ name.splice(i, 1);
+ i -= 1;
+ } else if (part === '..') {
+ // If at the start, or previous value is still ..,
+ // keep them so that when converted to a path it may
+ // still work when converted to a path, even though
+ // as an ID it is less than ideal. In larger point
+ // releases, may be better to just kick out an error.
+ if (i === 0 || (i === 1 && name[2] === '..') || name[i - 1] === '..') {
+ continue;
+ } else if (i > 0) {
+ name.splice(i - 1, 2);
+ i -= 2;
}
}
- //end trimDots
-
- name = name.join("/");
- } else if (name.indexOf('./') === 0) {
- // No baseName, so this is ID is resolved relative
- // to baseUrl, pull off the leading dot.
- name = name.substring(2);
}
+ //end trimDots
+
+ name = name.join('/');
}
//Apply map config if available.
@@ -230,32 +240,39 @@ var requirejs, require, define;
return [prefix, name];
}
+ //Creates a parts array for a relName where first part is plugin ID,
+ //second part is resource ID. Assumes relName has already been normalized.
+ function makeRelParts(relName) {
+ return relName ? splitPrefix(relName) : [];
+ }
+
/**
* Makes a name map, normalizing the name, and using a plugin
* for normalization if necessary. Grabs a ref to plugin
* too, as an optimization.
*/
- makeMap = function (name, relName) {
+ makeMap = function (name, relParts) {
var plugin,
parts = splitPrefix(name),
- prefix = parts[0];
+ prefix = parts[0],
+ relResourceName = relParts[1];
name = parts[1];
if (prefix) {
- prefix = normalize(prefix, relName);
+ prefix = normalize(prefix, relResourceName);
plugin = callDep(prefix);
}
//Normalize according
if (prefix) {
if (plugin && plugin.normalize) {
- name = plugin.normalize(name, makeNormalize(relName));
+ name = plugin.normalize(name, makeNormalize(relResourceName));
} else {
- name = normalize(name, relName);
+ name = normalize(name, relResourceName);
}
} else {
- name = normalize(name, relName);
+ name = normalize(name, relResourceName);
parts = splitPrefix(name);
prefix = parts[0];
name = parts[1];
@@ -302,13 +319,14 @@ var requirejs, require, define;
};
main = function (name, deps, callback, relName) {
- var cjsModule, depName, ret, map, i,
+ var cjsModule, depName, ret, map, i, relParts,
args = [],
callbackType = typeof callback,
usingExports;
//Use name if no relName
relName = relName || name;
+ relParts = makeRelParts(relName);
//Call the callback to define the module, if necessary.
if (callbackType === 'undefined' || callbackType === 'function') {
@@ -317,7 +335,7 @@ var requirejs, require, define;
//Default to [require, exports, module] if no deps
deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
for (i = 0; i < deps.length; i += 1) {
- map = makeMap(deps[i], relName);
+ map = makeMap(deps[i], relParts);
depName = map.f;
//Fast path CommonJS standard dependencies.
@@ -373,7 +391,7 @@ var requirejs, require, define;
//deps arg is the module name, and second arg (if passed)
//is just the relName.
//Normalize module name, if it contains . or ..
- return callDep(makeMap(deps, callback).f);
+ return callDep(makeMap(deps, makeRelParts(callback)).f);
} else if (!deps.splice) {
//deps is a config object, not an array.
config = deps;
@@ -737,6 +755,12 @@ S2.define('select2/utils',[
});
};
+ Utils.entityDecode = function (html) {
+ var txt = document.createElement('textarea');
+ txt.innerHTML = html;
+ return txt.value;
+ }
+
// Append an array of jQuery nodes to a given element.
Utils.appendMany = function ($element, $nodes) {
// jQuery 1.7.x does not support $.fn.append() with an array
@@ -754,6 +778,14 @@ S2.define('select2/utils',[
$element.append($nodes);
};
+ // Determine whether the browser is on a touchscreen device.
+ Utils.isTouchscreen = function() {
+ if ('undefined' === typeof Utils._isTouchscreenCache) {
+ Utils._isTouchscreenCache = 'ontouchstart' in document.documentElement;
+ }
+ return Utils._isTouchscreenCache;
+ }
+
return Utils;
});
@@ -773,7 +805,7 @@ S2.define('select2/results',[
Results.prototype.render = function () {
var $results = $(
- '
'
+ '
'
);
if (this.options.get('multiple')) {
@@ -796,7 +828,7 @@ S2.define('select2/results',[
this.hideLoading();
var $message = $(
- ''
);
@@ -858,9 +890,9 @@ S2.define('select2/results',[
Results.prototype.highlightFirstItem = function () {
var $options = this.$results
- .find('.select2-results__option[aria-selected]');
+ .find('.select2-results__option[data-selected]');
- var $selected = $options.filter('[aria-selected=true]');
+ var $selected = $options.filter('[data-selected=true]');
// Check if there are any selected options
if ($selected.length > 0) {
@@ -884,7 +916,7 @@ S2.define('select2/results',[
});
var $options = self.$results
- .find('.select2-results__option[aria-selected]');
+ .find('.select2-results__option[data-selected]');
$options.each(function () {
var $option = $(this);
@@ -896,9 +928,9 @@ S2.define('select2/results',[
if ((item.element != null && item.element.selected) ||
(item.element == null && $.inArray(id, selectedIds) > -1)) {
- $option.attr('aria-selected', 'true');
+ $option.attr('data-selected', 'true');
} else {
- $option.attr('aria-selected', 'false');
+ $option.attr('data-selected', 'false');
}
});
@@ -930,17 +962,18 @@ S2.define('select2/results',[
option.className = 'select2-results__option';
var attrs = {
- 'role': 'treeitem',
- 'aria-selected': 'false'
+ 'role': 'option',
+ 'data-selected': 'false',
+ 'tabindex': -1
};
if (data.disabled) {
- delete attrs['aria-selected'];
+ delete attrs['data-selected'];
attrs['aria-disabled'] = 'true';
}
if (data.id == null) {
- delete attrs['aria-selected'];
+ delete attrs['data-selected'];
}
if (data._resultId != null) {
@@ -952,9 +985,8 @@ S2.define('select2/results',[
}
if (data.children) {
- attrs.role = 'group';
attrs['aria-label'] = data.text;
- delete attrs['aria-selected'];
+ delete attrs['data-selected'];
}
for (var attr in attrs) {
@@ -971,6 +1003,7 @@ S2.define('select2/results',[
var $label = $(label);
this.template(data, label);
+ $label.attr('role', 'presentation');
var $children = [];
@@ -983,10 +1016,11 @@ S2.define('select2/results',[
}
var $childrenContainer = $('
', {
- 'class': 'select2-results__options select2-results__options--nested'
+ 'class': 'select2-results__options select2-results__options--nested',
+ 'role': 'listbox'
});
-
$childrenContainer.append($children);
+ $option.attr('role', 'list');
$option.append(label);
$option.append($childrenContainer);
@@ -1082,7 +1116,7 @@ S2.define('select2/results',[
var data = $highlighted.data('data');
- if ($highlighted.attr('aria-selected') == 'true') {
+ if ($highlighted.attr('data-selected') == 'true') {
self.trigger('close', {});
} else {
self.trigger('select', {
@@ -1094,7 +1128,7 @@ S2.define('select2/results',[
container.on('results:previous', function () {
var $highlighted = self.getHighlightedResults();
- var $options = self.$results.find('[aria-selected]');
+ var $options = self.$results.find('[data-selected]');
var currentIndex = $options.index($highlighted);
@@ -1128,7 +1162,7 @@ S2.define('select2/results',[
container.on('results:next', function () {
var $highlighted = self.getHighlightedResults();
- var $options = self.$results.find('[aria-selected]');
+ var $options = self.$results.find('[data-selected]');
var currentIndex = $options.index($highlighted);
@@ -1156,7 +1190,8 @@ S2.define('select2/results',[
});
container.on('results:focus', function (params) {
- params.element.addClass('select2-results__option--highlighted');
+ params.element.addClass('select2-results__option--highlighted').attr('aria-selected', 'true');
+ self.$results.attr('aria-activedescendant', params.element.attr('id'));
});
container.on('results:message', function (params) {
@@ -1188,13 +1223,13 @@ S2.define('select2/results',[
});
}
- this.$results.on('mouseup', '.select2-results__option[aria-selected]',
+ this.$results.on('mouseup', '.select2-results__option[data-selected]',
function (evt) {
var $this = $(this);
var data = $this.data('data');
- if ($this.attr('aria-selected') === 'true') {
+ if ($this.attr('data-selected') === 'true') {
if (self.options.get('multiple')) {
self.trigger('unselect', {
originalEvent: evt,
@@ -1213,12 +1248,13 @@ S2.define('select2/results',[
});
});
- this.$results.on('mouseenter', '.select2-results__option[aria-selected]',
+ this.$results.on('mouseenter', '.select2-results__option[data-selected]',
function (evt) {
var data = $(this).data('data');
self.getHighlightedResults()
- .removeClass('select2-results__option--highlighted');
+ .removeClass('select2-results__option--highlighted')
+ .attr('aria-selected', 'false');
self.trigger('results:focus', {
data: data,
@@ -1245,7 +1281,7 @@ S2.define('select2/results',[
return;
}
- var $options = this.$results.find('[aria-selected]');
+ var $options = this.$results.find('[data-selected]');
var currentIndex = $options.index($highlighted);
@@ -1323,7 +1359,7 @@ S2.define('select2/selection/base',[
BaseSelection.prototype.render = function () {
var $selection = $(
- '' +
''
);
@@ -1349,6 +1385,7 @@ S2.define('select2/selection/base',[
var id = container.id + '-container';
var resultsId = container.id + '-results';
+ var searchHidden = this.options.get('minimumResultsForSearch') === Infinity;
this.container = container;
@@ -1390,7 +1427,11 @@ S2.define('select2/selection/base',[
self.$selection.removeAttr('aria-activedescendant');
self.$selection.removeAttr('aria-owns');
- self.$selection.focus();
+ // This needs to be delayed as the active element is the body when the
+ // key is pressed.
+ window.setTimeout(function () {
+ self.$selection.focus();
+ }, 1);
self._detachCloseHandler(container);
});
@@ -1440,8 +1481,14 @@ S2.define('select2/selection/base',[
}
var $element = $this.data('element');
-
$element.select2('close');
+
+ // Remove any focus when dropdown is closed by clicking outside the select area.
+ // Timeout of 1 required for close to finish wrapping up.
+ setTimeout(function(){
+ $this.find('*:focus').blur();
+ $target.focus();
+ }, 1);
});
});
};
@@ -1500,8 +1547,21 @@ S2.define('select2/selection/single',[
var id = container.id + '-container';
- this.$selection.find('.select2-selection__rendered').attr('id', id);
- this.$selection.attr('aria-labelledby', id);
+ this.$selection.find('.select2-selection__rendered')
+ .attr('id', id)
+ .attr('role', 'textbox')
+ .attr('aria-readonly', 'true');
+
+ var label = this.options.get( 'label' );
+
+ if ( typeof( label ) === 'string' ) {
+ this.$selection.attr( 'aria-label', label );
+ } else {
+ this.$selection.attr( 'aria-labelledby', id );
+ }
+
+ // This makes single non-search selects work in screen readers. If it causes problems elsewhere, remove.
+ this.$selection.attr('role', 'combobox');
this.$selection.on('mousedown', function (evt) {
// Only respond to left clicks
@@ -1518,6 +1578,13 @@ S2.define('select2/selection/single',[
// User focuses on the container
});
+ this.$selection.on('keydown', function (evt) {
+ // If user starts typing an alphanumeric key on the keyboard, open if not opened.
+ if (!container.isOpen() && evt.which >= 48 && evt.which <= 90) {
+ container.open();
+ }
+ });
+
this.$selection.on('blur', function (evt) {
// User exits the container
});
@@ -1557,9 +1624,9 @@ S2.define('select2/selection/single',[
var selection = data[0];
var $rendered = this.$selection.find('.select2-selection__rendered');
- var formatted = this.display(selection, $rendered);
+ var formatted = Utils.entityDecode(this.display(selection, $rendered));
- $rendered.empty().append(formatted);
+ $rendered.empty().text(formatted);
$rendered.prop('title', selection.title || selection.text);
};
@@ -1583,7 +1650,7 @@ S2.define('select2/selection/multiple',[
$selection.addClass('select2-selection--multiple');
$selection.html(
- '
'
+ '
'
);
return $selection;
@@ -1620,6 +1687,18 @@ S2.define('select2/selection/multiple',[
});
}
);
+
+ this.$selection.on('keydown', function (evt) {
+ // If user starts typing an alphanumeric key on the keyboard, open if not opened.
+ if (!container.isOpen() && evt.which >= 48 && evt.which <= 90) {
+ container.open();
+ }
+ });
+
+ // Focus on the search field when the container is focused instead of the main container.
+ container.on( 'focus', function(){
+ self.focusOnSearch();
+ });
};
MultipleSelection.prototype.clear = function () {
@@ -1636,7 +1715,7 @@ S2.define('select2/selection/multiple',[
MultipleSelection.prototype.selectionContainer = function () {
var $container = $(
'
' +
- '' +
+ '' +
'×' +
'' +
'
'
@@ -1645,6 +1724,24 @@ S2.define('select2/selection/multiple',[
return $container;
};
+ /**
+ * Focus on the search field instead of the main multiselect container.
+ */
+ MultipleSelection.prototype.focusOnSearch = function() {
+ var self = this;
+
+ if ('undefined' !== typeof self.$search) {
+ // Needs 1 ms delay because of other 1 ms setTimeouts when rendering.
+ setTimeout(function(){
+ // Prevent the dropdown opening again when focused from this.
+ // This gets reset automatically when focus is triggered.
+ self._keyUpPrevented = true;
+
+ self.$search.focus();
+ }, 1);
+ }
+ }
+
MultipleSelection.prototype.update = function (data) {
this.clear();
@@ -1658,9 +1755,14 @@ S2.define('select2/selection/multiple',[
var selection = data[d];
var $selection = this.selectionContainer();
+ var removeItemTag = $selection.html();
var formatted = this.display(selection, $selection);
+ if ('string' === typeof formatted) {
+ formatted = Utils.entityDecode(formatted.trim());
+ }
- $selection.append(formatted);
+ $selection.text(formatted);
+ $selection.prepend(removeItemTag);
$selection.prop('title', selection.title || selection.text);
$selection.data('data', selection);
@@ -1699,7 +1801,7 @@ S2.define('select2/selection/placeholder',[
Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
var $placeholder = this.selectionContainer();
- $placeholder.html(this.display(placeholder));
+ $placeholder.text(Utils.entityDecode(this.display(placeholder)));
$placeholder.addClass('select2-selection__placeholder')
.removeClass('select2-selection__choice');
@@ -1836,8 +1938,8 @@ S2.define('select2/selection/search',[
Search.prototype.render = function (decorated) {
var $search = $(
'
' +
- '' +
'
'
);
@@ -1854,16 +1956,19 @@ S2.define('select2/selection/search',[
Search.prototype.bind = function (decorated, container, $container) {
var self = this;
+ var resultsId = container.id + '-results';
decorated.call(this, container, $container);
container.on('open', function () {
+ self.$search.attr('aria-owns', resultsId);
self.$search.trigger('focus');
});
container.on('close', function () {
self.$search.val('');
self.$search.removeAttr('aria-activedescendant');
+ self.$search.removeAttr('aria-owns');
self.$search.trigger('focus');
});
@@ -1882,7 +1987,7 @@ S2.define('select2/selection/search',[
});
container.on('results:focus', function (params) {
- self.$search.attr('aria-activedescendant', params.id);
+ self.$search.attr('aria-activedescendant', params.data._resultId);
});
this.$selection.on('focusin', '.select2-search--inline', function (evt) {
@@ -1913,6 +2018,9 @@ S2.define('select2/selection/search',[
evt.preventDefault();
}
+ } else if (evt.which === KEYS.ENTER) {
+ container.open();
+ evt.preventDefault();
}
});
@@ -3004,8 +3112,15 @@ S2.define('select2/data/base',[
};
BaseAdapter.prototype.generateResultId = function (container, data) {
- var id = container.id + '-result-';
+ var id = '';
+ if (container != null) {
+ id += container.id
+ } else {
+ id += Utils.generateChars(4);
+ }
+
+ id += '-result-';
id += Utils.generateChars(4);
if (data.id != null) {
@@ -3191,7 +3306,7 @@ S2.define('select2/data/select',[
}
}
- if (data.id) {
+ if (data.id !== undefined) {
option.value = data.id;
}
@@ -3289,7 +3404,7 @@ S2.define('select2/data/select',[
item.text = item.text.toString();
}
- if (item._resultId == null && item.id && this.container != null) {
+ if (item._resultId == null && item.id) {
item._resultId = this.generateResultId(this.container, item);
}
@@ -3466,6 +3581,7 @@ S2.define('select2/data/ajax',[
}
callback(results);
+ self.container.focusOnActiveElement();
}, function () {
// Attempt to detect if a request was aborted
// Only works if the transport exposes a status property
@@ -3550,7 +3666,10 @@ S2.define('select2/data/tags',[
}, true)
);
- var checkText = option.text === params.term;
+ var optionText = (option.text || '').toUpperCase();
+ var paramsTerm = (params.term || '').toUpperCase();
+
+ var checkText = optionText === paramsTerm;
if (checkText || checkChildren) {
if (child) {
@@ -3887,9 +4006,9 @@ S2.define('select2/dropdown/search',[
var $search = $(
'' +
- '' +
+ '' +
''
);
@@ -3903,6 +4022,7 @@ S2.define('select2/dropdown/search',[
Search.prototype.bind = function (decorated, container, $container) {
var self = this;
+ var resultsId = container.id + '-results';
decorated.call(this, container, $container);
@@ -3926,7 +4046,7 @@ S2.define('select2/dropdown/search',[
container.on('open', function () {
self.$search.attr('tabindex', 0);
-
+ self.$search.attr('aria-owns', resultsId);
self.$search.focus();
window.setTimeout(function () {
@@ -3936,12 +4056,13 @@ S2.define('select2/dropdown/search',[
container.on('close', function () {
self.$search.attr('tabindex', -1);
-
+ self.$search.removeAttr('aria-activedescendant');
+ self.$search.removeAttr('aria-owns');
self.$search.val('');
});
container.on('focus', function () {
- if (container.isOpen()) {
+ if (!container.isOpen()) {
self.$search.focus();
}
});
@@ -3957,6 +4078,10 @@ S2.define('select2/dropdown/search',[
}
}
});
+
+ container.on('results:focus', function (params) {
+ self.$search.attr('aria-activedescendant', params.data._resultId);
+ });
};
Search.prototype.handleSearch = function (evt) {
@@ -4098,7 +4223,7 @@ S2.define('select2/dropdown/infiniteScroll',[
var $option = $(
''
+ 'role="option" aria-disabled="true">'
);
var message = this.options.get('translations').get('loadingMore');
@@ -5344,16 +5469,22 @@ S2.define('select2/core',[
});
});
- this.on('keypress', function (evt) {
- var key = evt.which;
+ this.on('open', function(){
+ // Focus on the active element when opening dropdown.
+ // Needs 1 ms delay because of other 1 ms setTimeouts when rendering.
+ setTimeout(function(){
+ self.focusOnActiveElement();
+ }, 1);
+ });
+ $(document).on('keydown', function (evt) {
+ var key = evt.which;
if (self.isOpen()) {
- if (key === KEYS.ESC || key === KEYS.TAB ||
- (key === KEYS.UP && evt.altKey)) {
+ if (key === KEYS.ESC || (key === KEYS.UP && evt.altKey)) {
self.close();
evt.preventDefault();
- } else if (key === KEYS.ENTER) {
+ } else if (key === KEYS.ENTER || key === KEYS.TAB) {
self.trigger('results:select', {});
evt.preventDefault();
@@ -5370,17 +5501,42 @@ S2.define('select2/core',[
evt.preventDefault();
}
- } else {
- if (key === KEYS.ENTER || key === KEYS.SPACE ||
- (key === KEYS.DOWN && evt.altKey)) {
- self.open();
+ var $searchField = self.$dropdown.find('.select2-search__field');
+ if (! $searchField.length) {
+ $searchField = self.$container.find('.select2-search__field');
+ }
+
+ // Move the focus to the selected element on keyboard navigation.
+ // Required for screen readers to work properly.
+ if (key === KEYS.DOWN || key === KEYS.UP) {
+ self.focusOnActiveElement();
+ } else {
+ // Focus on the search if user starts typing.
+ $searchField.focus();
+ // Focus back to active selection when finished typing.
+ // Small delay so typed character can be read by screen reader.
+ setTimeout(function(){
+ self.focusOnActiveElement();
+ }, 1000);
+ }
+ } else if (self.hasFocus()) {
+ if (key === KEYS.ENTER || key === KEYS.SPACE ||
+ key === KEYS.DOWN) {
+ self.open();
evt.preventDefault();
}
}
});
};
+ Select2.prototype.focusOnActiveElement = function () {
+ // Don't mess with the focus on touchscreens because it causes havoc with on-screen keyboards.
+ if (this.isOpen() && ! Utils.isTouchscreen()) {
+ this.$results.find('li.select2-results__option--highlighted').focus();
+ }
+ };
+
Select2.prototype._syncAttributes = function () {
this.options.set('disabled', this.$element.prop('disabled'));
@@ -5653,11 +5809,11 @@ S2.define('jquery.select2',[
'./select2/core',
'./select2/defaults'
], function ($, _, Select2, Defaults) {
- if ($.fn.select2 == null) {
+ if ($.fn.selectWoo == null) {
// All methods that should return the element
var thisMethods = ['open', 'close', 'destroy'];
- $.fn.select2 = function (options) {
+ $.fn.selectWoo = function (options) {
options = options || {};
if (typeof options === 'object') {
@@ -5697,10 +5853,17 @@ S2.define('jquery.select2',[
};
}
- if ($.fn.select2.defaults == null) {
- $.fn.select2.defaults = Defaults;
+ if ($.fn.select2 != null && $.fn.select2.defaults != null) {
+ $.fn.selectWoo.defaults = $.fn.select2.defaults;
}
+ if ($.fn.selectWoo.defaults == null) {
+ $.fn.selectWoo.defaults = Defaults;
+ }
+
+ // Also register selectWoo under select2 if select2 is not already present.
+ $.fn.select2 = $.fn.select2 || $.fn.selectWoo;
+
return Select2;
});
@@ -5719,6 +5882,7 @@ S2.define('jquery.select2',[
// This allows Select2 to use the internal loader outside of this file, such
// as in the language files.
jQuery.fn.select2.amd = S2;
+ jQuery.fn.selectWoo.amd = S2;
// Return the Select2 instance for anyone who is importing it.
return select2;
diff --git a/assets/js/selectWoo/selectWoo.full.js b/assets/js/selectWoo/selectWoo.full.js
index 23548fce727..49cb11ee692 100644
--- a/assets/js/selectWoo/selectWoo.full.js
+++ b/assets/js/selectWoo/selectWoo.full.js
@@ -1,5 +1,5 @@
/*!
- * SelectWoo 1.0.6
+ * SelectWoo 1.0.9
* https://github.com/woocommerce/selectWoo
*
* Released under the MIT license
@@ -755,8 +755,8 @@ S2.define('select2/utils',[
});
};
- Utils.entityDecode = function(html) {
- var txt = document.createElement("textarea");
+ Utils.entityDecode = function (html) {
+ var txt = document.createElement('textarea');
txt.innerHTML = html;
return txt.value;
}
@@ -1551,7 +1551,14 @@ S2.define('select2/selection/single',[
.attr('id', id)
.attr('role', 'textbox')
.attr('aria-readonly', 'true');
- this.$selection.attr('aria-labelledby', id);
+
+ var label = this.options.get( 'label' );
+
+ if ( typeof( label ) === 'string' ) {
+ this.$selection.attr( 'aria-label', label );
+ } else {
+ this.$selection.attr( 'aria-labelledby', id );
+ }
// This makes single non-search selects work in screen readers. If it causes problems elsewhere, remove.
this.$selection.attr('role', 'combobox');
diff --git a/assets/js/selectWoo/selectWoo.js b/assets/js/selectWoo/selectWoo.js
index f4dc2bda2ca..3f27bbd4032 100644
--- a/assets/js/selectWoo/selectWoo.js
+++ b/assets/js/selectWoo/selectWoo.js
@@ -1,5 +1,5 @@
/*!
- * SelectWoo 1.0.6
+ * SelectWoo 1.0.9
* https://github.com/woocommerce/selectWoo
*
* Released under the MIT license
@@ -755,8 +755,8 @@ S2.define('select2/utils',[
});
};
- Utils.entityDecode = function(html) {
- var txt = document.createElement("textarea");
+ Utils.entityDecode = function (html) {
+ var txt = document.createElement('textarea');
txt.innerHTML = html;
return txt.value;
}
@@ -1551,7 +1551,14 @@ S2.define('select2/selection/single',[
.attr('id', id)
.attr('role', 'textbox')
.attr('aria-readonly', 'true');
- this.$selection.attr('aria-labelledby', id);
+
+ var label = this.options.get( 'label' );
+
+ if ( typeof( label ) === 'string' ) {
+ this.$selection.attr( 'aria-label', label );
+ } else {
+ this.$selection.attr( 'aria-labelledby', id );
+ }
// This makes single non-search selects work in screen readers. If it causes problems elsewhere, remove.
this.$selection.attr('role', 'combobox');
diff --git a/bin/composer/mozart/composer.lock b/bin/composer/mozart/composer.lock
index 1a3ce3075fe..6e9a52a1179 100644
--- a/bin/composer/mozart/composer.lock
+++ b/bin/composer/mozart/composer.lock
@@ -33,6 +33,7 @@
"squizlabs/php_codesniffer": "^3.5",
"vimeo/psalm": "^4.4"
},
+ "default-branch": true,
"bin": [
"bin/mozart"
],
@@ -53,6 +54,10 @@
}
],
"description": "Composes all dependencies as a package inside a WordPress plugin",
+ "support": {
+ "issues": "https://github.com/coenjacobs/mozart/issues",
+ "source": "https://github.com/coenjacobs/mozart/tree/master"
+ },
"funding": [
{
"url": "https://github.com/coenjacobs",
@@ -144,6 +149,10 @@
"sftp",
"storage"
],
+ "support": {
+ "issues": "https://github.com/thephpleague/flysystem/issues",
+ "source": "https://github.com/thephpleague/flysystem/tree/1.x"
+ },
"funding": [
{
"url": "https://offset.earth/frankdejonge",
@@ -192,6 +201,10 @@
}
],
"description": "Mime-type detection for Flysystem",
+ "support": {
+ "issues": "https://github.com/thephpleague/mime-type-detection/issues",
+ "source": "https://github.com/thephpleague/mime-type-detection/tree/1.7.0"
+ },
"funding": [
{
"url": "https://github.com/frankdejonge",
@@ -206,27 +219,22 @@
},
{
"name": "psr/container",
- "version": "1.0.0",
+ "version": "1.1.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/container.git",
- "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
+ "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
- "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf",
+ "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf",
"shasum": ""
},
"require": {
- "php": ">=5.3.0"
+ "php": ">=7.2.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
"autoload": {
"psr-4": {
"Psr\\Container\\": "src/"
@@ -239,7 +247,7 @@
"authors": [
{
"name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
+ "homepage": "https://www.php-fig.org/"
}
],
"description": "Common Container Interface (PHP FIG PSR-11)",
@@ -253,22 +261,22 @@
],
"support": {
"issues": "https://github.com/php-fig/container/issues",
- "source": "https://github.com/php-fig/container/tree/master"
+ "source": "https://github.com/php-fig/container/tree/1.1.1"
},
- "time": "2017-02-14T16:28:37+00:00"
+ "time": "2021-03-05T17:36:06+00:00"
},
{
"name": "symfony/console",
- "version": "v5.2.3",
+ "version": "v5.2.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "89d4b176d12a2946a1ae4e34906a025b7b6b135a"
+ "reference": "35f039df40a3b335ebf310f244cb242b3a83ac8d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/89d4b176d12a2946a1ae4e34906a025b7b6b135a",
- "reference": "89d4b176d12a2946a1ae4e34906a025b7b6b135a",
+ "url": "https://api.github.com/repos/symfony/console/zipball/35f039df40a3b335ebf310f244cb242b3a83ac8d",
+ "reference": "35f039df40a3b335ebf310f244cb242b3a83ac8d",
"shasum": ""
},
"require": {
@@ -335,6 +343,9 @@
"console",
"terminal"
],
+ "support": {
+ "source": "https://github.com/symfony/console/tree/v5.2.6"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -349,20 +360,20 @@
"type": "tidelift"
}
],
- "time": "2021-01-28T22:06:19+00:00"
+ "time": "2021-03-28T09:42:18+00:00"
},
{
"name": "symfony/finder",
- "version": "v5.2.3",
+ "version": "v5.2.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "4adc8d172d602008c204c2e16956f99257248e03"
+ "reference": "0d639a0943822626290d169965804f79400e6a04"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/4adc8d172d602008c204c2e16956f99257248e03",
- "reference": "4adc8d172d602008c204c2e16956f99257248e03",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/0d639a0943822626290d169965804f79400e6a04",
+ "reference": "0d639a0943822626290d169965804f79400e6a04",
"shasum": ""
},
"require": {
@@ -393,6 +404,9 @@
],
"description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/finder/tree/v5.2.4"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -407,11 +421,11 @@
"type": "tidelift"
}
],
- "time": "2021-01-28T22:06:19+00:00"
+ "time": "2021-02-15T18:55:04+00:00"
},
{
"name": "symfony/polyfill-ctype",
- "version": "v1.22.0",
+ "version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
@@ -469,6 +483,9 @@
"polyfill",
"portable"
],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -487,16 +504,16 @@
},
{
"name": "symfony/polyfill-intl-grapheme",
- "version": "v1.22.0",
+ "version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
- "reference": "267a9adeb8ecb8071040a740930e077cdfb987af"
+ "reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/267a9adeb8ecb8071040a740930e077cdfb987af",
- "reference": "267a9adeb8ecb8071040a740930e077cdfb987af",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/5601e09b69f26c1828b13b6bb87cb07cddba3170",
+ "reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170",
"shasum": ""
},
"require": {
@@ -547,6 +564,9 @@
"portable",
"shim"
],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.22.1"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -561,20 +581,20 @@
"type": "tidelift"
}
],
- "time": "2021-01-07T16:49:33+00:00"
+ "time": "2021-01-22T09:19:47+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
- "version": "v1.22.0",
+ "version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
- "reference": "6e971c891537eb617a00bb07a43d182a6915faba"
+ "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/6e971c891537eb617a00bb07a43d182a6915faba",
- "reference": "6e971c891537eb617a00bb07a43d182a6915faba",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/43a0283138253ed1d48d352ab6d0bdb3f809f248",
+ "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248",
"shasum": ""
},
"require": {
@@ -628,6 +648,9 @@
"portable",
"shim"
],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.1"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -642,20 +665,20 @@
"type": "tidelift"
}
],
- "time": "2021-01-07T17:09:11+00:00"
+ "time": "2021-01-22T09:19:47+00:00"
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.22.0",
+ "version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13"
+ "reference": "5232de97ee3b75b0360528dae24e73db49566ab1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f377a3dd1fde44d37b9831d68dc8dea3ffd28e13",
- "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1",
+ "reference": "5232de97ee3b75b0360528dae24e73db49566ab1",
"shasum": ""
},
"require": {
@@ -705,6 +728,9 @@
"portable",
"shim"
],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.1"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -719,11 +745,11 @@
"type": "tidelift"
}
],
- "time": "2021-01-07T16:49:33+00:00"
+ "time": "2021-01-22T09:19:47+00:00"
},
{
"name": "symfony/polyfill-php73",
- "version": "v1.22.0",
+ "version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php73.git",
@@ -781,6 +807,9 @@
"portable",
"shim"
],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php73/tree/v1.22.1"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -799,7 +828,7 @@
},
{
"name": "symfony/polyfill-php80",
- "version": "v1.22.0",
+ "version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
@@ -861,6 +890,9 @@
"portable",
"shim"
],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.1"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -937,6 +969,9 @@
"interoperability",
"standards"
],
+ "support": {
+ "source": "https://github.com/symfony/service-contracts/tree/master"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -955,16 +990,16 @@
},
{
"name": "symfony/string",
- "version": "v5.2.3",
+ "version": "v5.2.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
- "reference": "c95468897f408dd0aca2ff582074423dd0455122"
+ "reference": "ad0bd91bce2054103f5eaa18ebeba8d3bc2a0572"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/string/zipball/c95468897f408dd0aca2ff582074423dd0455122",
- "reference": "c95468897f408dd0aca2ff582074423dd0455122",
+ "url": "https://api.github.com/repos/symfony/string/zipball/ad0bd91bce2054103f5eaa18ebeba8d3bc2a0572",
+ "reference": "ad0bd91bce2054103f5eaa18ebeba8d3bc2a0572",
"shasum": ""
},
"require": {
@@ -1017,6 +1052,9 @@
"utf-8",
"utf8"
],
+ "support": {
+ "source": "https://github.com/symfony/string/tree/v5.2.6"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -1031,7 +1069,7 @@
"type": "tidelift"
}
],
- "time": "2021-01-25T15:14:59+00:00"
+ "time": "2021-03-17T17:12:15+00:00"
}
],
"aliases": [],
@@ -1046,5 +1084,5 @@
"platform-overrides": {
"php": "7.3"
},
- "plugin-api-version": "1.1.0"
+ "plugin-api-version": "2.0.0"
}
diff --git a/bin/composer/phpcs/composer.lock b/bin/composer/phpcs/composer.lock
index 5a70d30ff7e..d784a60a0a0 100644
--- a/bin/composer/phpcs/composer.lock
+++ b/bin/composer/phpcs/composer.lock
@@ -71,6 +71,10 @@
"stylecheck",
"tests"
],
+ "support": {
+ "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues",
+ "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer"
+ },
"time": "2020-06-25T14:57:39+00:00"
},
{
@@ -129,32 +133,36 @@
"phpcs",
"standards"
],
+ "support": {
+ "issues": "https://github.com/PHPCompatibility/PHPCompatibility/issues",
+ "source": "https://github.com/PHPCompatibility/PHPCompatibility"
+ },
"time": "2019-12-27T09:44:58+00:00"
},
{
"name": "phpcompatibility/phpcompatibility-paragonie",
- "version": "1.3.0",
+ "version": "1.3.1",
"source": {
"type": "git",
"url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git",
- "reference": "b862bc32f7e860d0b164b199bd995e690b4b191c"
+ "reference": "ddabec839cc003651f2ce695c938686d1086cf43"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/b862bc32f7e860d0b164b199bd995e690b4b191c",
- "reference": "b862bc32f7e860d0b164b199bd995e690b4b191c",
+ "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/ddabec839cc003651f2ce695c938686d1086cf43",
+ "reference": "ddabec839cc003651f2ce695c938686d1086cf43",
"shasum": ""
},
"require": {
"phpcompatibility/php-compatibility": "^9.0"
},
"require-dev": {
- "dealerdirect/phpcodesniffer-composer-installer": "^0.5",
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.7",
"paragonie/random_compat": "dev-master",
"paragonie/sodium_compat": "dev-master"
},
"suggest": {
- "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.",
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.",
"roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
},
"type": "phpcodesniffer-standard",
@@ -181,7 +189,11 @@
"polyfill",
"standards"
],
- "time": "2019-11-04T15:17:54+00:00"
+ "support": {
+ "issues": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/issues",
+ "source": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie"
+ },
+ "time": "2021-02-15T10:24:51+00:00"
},
{
"name": "phpcompatibility/phpcompatibility-wp",
@@ -231,6 +243,10 @@
"standards",
"wordpress"
],
+ "support": {
+ "issues": "https://github.com/PHPCompatibility/PHPCompatibilityWP/issues",
+ "source": "https://github.com/PHPCompatibility/PHPCompatibilityWP"
+ },
"time": "2019-08-28T14:22:28+00:00"
},
{
@@ -327,6 +343,10 @@
"woocommerce",
"wordpress"
],
+ "support": {
+ "issues": "https://github.com/woocommerce/woocommerce-sniffs/issues",
+ "source": "https://github.com/woocommerce/woocommerce-sniffs/tree/master"
+ },
"time": "2020-08-06T18:23:45+00:00"
},
{
@@ -373,6 +393,11 @@
"standards",
"wordpress"
],
+ "support": {
+ "issues": "https://github.com/WordPress/WordPress-Coding-Standards/issues",
+ "source": "https://github.com/WordPress/WordPress-Coding-Standards",
+ "wiki": "https://github.com/WordPress/WordPress-Coding-Standards/wiki"
+ },
"time": "2020-05-13T23:57:56+00:00"
}
],
@@ -386,5 +411,5 @@
"platform-overrides": {
"php": "7.0"
},
- "plugin-api-version": "1.1.0"
+ "plugin-api-version": "2.0.0"
}
diff --git a/bin/composer/phpunit/composer.lock b/bin/composer/phpunit/composer.lock
index d1c92edd290..b32d4d77b22 100644
--- a/bin/composer/phpunit/composer.lock
+++ b/bin/composer/phpunit/composer.lock
@@ -332,6 +332,10 @@
}
],
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+ "support": {
+ "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
+ "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/release/4.x"
+ },
"time": "2019-12-28T18:55:12+00:00"
},
{
@@ -444,6 +448,10 @@
"spy",
"stub"
],
+ "support": {
+ "issues": "https://github.com/phpspec/prophecy/issues",
+ "source": "https://github.com/phpspec/prophecy/tree/v1.10.3"
+ },
"time": "2020-03-05T15:02:03+00:00"
},
{
@@ -604,6 +612,10 @@
"keywords": [
"template"
],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
+ "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1"
+ },
"time": "2015-06-21T13:50:34+00:00"
},
{
@@ -1224,6 +1236,10 @@
"keywords": [
"global state"
],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/global-state/issues",
+ "source": "https://github.com/sebastianbergmann/global-state/tree/2.0.0"
+ },
"time": "2017-04-27T15:39:26+00:00"
},
{
@@ -1488,6 +1504,10 @@
],
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
"homepage": "https://github.com/sebastianbergmann/version",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/version/issues",
+ "source": "https://github.com/sebastianbergmann/version/tree/master"
+ },
"time": "2016-10-03T07:35:21+00:00"
},
{
@@ -1607,6 +1627,10 @@
}
],
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
+ "support": {
+ "issues": "https://github.com/theseer/tokenizer/issues",
+ "source": "https://github.com/theseer/tokenizer/tree/master"
+ },
"time": "2019-06-13T22:48:21+00:00"
},
{
@@ -1656,6 +1680,10 @@
"check",
"validate"
],
+ "support": {
+ "issues": "https://github.com/webmozarts/assert/issues",
+ "source": "https://github.com/webmozarts/assert/tree/1.9.1"
+ },
"time": "2020-07-08T17:02:28+00:00"
}
],
@@ -1669,5 +1697,5 @@
"platform-overrides": {
"php": "7.0"
},
- "plugin-api-version": "1.1.0"
+ "plugin-api-version": "2.0.0"
}
diff --git a/bin/composer/wp/composer.lock b/bin/composer/wp/composer.lock
index 24fdbbf28cb..8fb33475e13 100644
--- a/bin/composer/wp/composer.lock
+++ b/bin/composer/wp/composer.lock
@@ -9,16 +9,16 @@
"packages-dev": [
{
"name": "gettext/gettext",
- "version": "v4.8.3",
+ "version": "v4.8.4",
"source": {
"type": "git",
"url": "https://github.com/php-gettext/Gettext.git",
- "reference": "57ff4fb16647e78e80a5909fe3c190f1c3110321"
+ "reference": "58bc0f7f37e78efb0f9758f93d4a0f669f0f84a1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-gettext/Gettext/zipball/57ff4fb16647e78e80a5909fe3c190f1c3110321",
- "reference": "57ff4fb16647e78e80a5909fe3c190f1c3110321",
+ "url": "https://api.github.com/repos/php-gettext/Gettext/zipball/58bc0f7f37e78efb0f9758f93d4a0f669f0f84a1",
+ "reference": "58bc0f7f37e78efb0f9758f93d4a0f669f0f84a1",
"shasum": ""
},
"require": {
@@ -70,9 +70,23 @@
"support": {
"email": "oom@oscarotero.com",
"issues": "https://github.com/oscarotero/Gettext/issues",
- "source": "https://github.com/php-gettext/Gettext/tree/v4.8.3"
+ "source": "https://github.com/php-gettext/Gettext/tree/v4.8.4"
},
- "time": "2020-11-18T22:35:49+00:00"
+ "funding": [
+ {
+ "url": "https://paypal.me/oscarotero",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/oscarotero",
+ "type": "github"
+ },
+ {
+ "url": "https://www.patreon.com/misteroom",
+ "type": "patreon"
+ }
+ ],
+ "time": "2021-03-10T19:35:49+00:00"
},
{
"name": "gettext/languages",
@@ -133,6 +147,10 @@
"translations",
"unicode"
],
+ "support": {
+ "issues": "https://github.com/php-gettext/Languages/issues",
+ "source": "https://github.com/php-gettext/Languages/tree/2.6.0"
+ },
"time": "2019-11-13T10:30:21+00:00"
},
{
@@ -178,6 +196,10 @@
}
],
"description": "Peast is PHP library that generates AST for JavaScript code",
+ "support": {
+ "issues": "https://github.com/mck89/peast/issues",
+ "source": "https://github.com/mck89/peast/tree/v1.12.0"
+ },
"time": "2021-01-08T15:16:19+00:00"
},
{
@@ -224,6 +246,10 @@
"mustache",
"templating"
],
+ "support": {
+ "issues": "https://github.com/bobthecow/mustache.php/issues",
+ "source": "https://github.com/bobthecow/mustache.php/tree/master"
+ },
"time": "2019-11-23T21:40:31+00:00"
},
{
@@ -273,6 +299,10 @@
"iri",
"sockets"
],
+ "support": {
+ "issues": "https://github.com/rmccue/Requests/issues",
+ "source": "https://github.com/rmccue/Requests/tree/master"
+ },
"time": "2016-10-13T00:11:37+00:00"
},
{
@@ -382,6 +412,10 @@
],
"description": "Provides internationalization tools for WordPress projects.",
"homepage": "https://github.com/wp-cli/i18n-command",
+ "support": {
+ "issues": "https://github.com/wp-cli/i18n-command/issues",
+ "source": "https://github.com/wp-cli/i18n-command/tree/v2.2.6"
+ },
"time": "2020-12-07T19:28:27+00:00"
},
{
@@ -430,20 +464,23 @@
],
"description": "A simple YAML loader/dumper class for PHP (WP-CLI fork)",
"homepage": "https://github.com/mustangostang/spyc/",
+ "support": {
+ "source": "https://github.com/wp-cli/spyc/tree/autoload"
+ },
"time": "2017-04-25T11:26:20+00:00"
},
{
"name": "wp-cli/php-cli-tools",
- "version": "v0.11.11",
+ "version": "v0.11.12",
"source": {
"type": "git",
"url": "https://github.com/wp-cli/php-cli-tools.git",
- "reference": "fe9c7c44a9e1bf2196ec51dc38da0593dbf2993f"
+ "reference": "e472e08489f7504d9e8c5c5a057e1419cd1b2b3e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/fe9c7c44a9e1bf2196ec51dc38da0593dbf2993f",
- "reference": "fe9c7c44a9e1bf2196ec51dc38da0593dbf2993f",
+ "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/e472e08489f7504d9e8c5c5a057e1419cd1b2b3e",
+ "reference": "e472e08489f7504d9e8c5c5a057e1419cd1b2b3e",
"shasum": ""
},
"require": {
@@ -463,15 +500,15 @@
"MIT"
],
"authors": [
- {
- "name": "James Logsdon",
- "email": "jlogsdon@php.net",
- "role": "Developer"
- },
{
"name": "Daniel Bachhuber",
"email": "daniel@handbuilt.co",
"role": "Maintainer"
+ },
+ {
+ "name": "James Logsdon",
+ "email": "jlogsdon@php.net",
+ "role": "Developer"
}
],
"description": "Console utilities for PHP",
@@ -480,7 +517,11 @@
"cli",
"console"
],
- "time": "2018-09-04T13:28:00+00:00"
+ "support": {
+ "issues": "https://github.com/wp-cli/php-cli-tools/issues",
+ "source": "https://github.com/wp-cli/php-cli-tools/tree/v0.11.12"
+ },
+ "time": "2021-03-03T12:43:49+00:00"
},
{
"name": "wp-cli/wp-cli",
@@ -542,6 +583,11 @@
"cli",
"wordpress"
],
+ "support": {
+ "docs": "https://make.wordpress.org/cli/handbook/",
+ "issues": "https://github.com/wp-cli/wp-cli/issues",
+ "source": "https://github.com/wp-cli/wp-cli"
+ },
"time": "2020-02-18T08:15:37+00:00"
}
],
@@ -555,5 +601,5 @@
"platform-overrides": {
"php": "7.0"
},
- "plugin-api-version": "1.1.0"
+ "plugin-api-version": "2.0.0"
}
diff --git a/changelog.txt b/changelog.txt
index a0491ef9f77..4b636018665 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,5 +1,276 @@
== Changelog ==
+= 5.2.2 2021-04-15 =
+
+**WooCommerce**
+
+* Fix - Can't grant permission for download from order details page. #29691
+
+= 5.2.1 2021-04-14 =
+
+**WooCommerce**
+
+* Update - WooCommerce Blocks package 4.7.2. #29660
+
+**WooCommerce Blocks - 4.7.2**
+
+* Fix - Check if Cart and Checkout are registered before removing payment methods. ([4056](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/4056))
+
+= 5.2.0 2021-04-13 =
+
+**WooCommerce**
+
+* Add - Filter woocommerce_product_recount_terms to allow/prevent recounting of product terms. #29281
+* Add - Result return array to the checkout_place_order_success callback to allow 3rd party to manipulate results. #29232
+* Dev - Fix miscellaneous typos in docblocks. #29285
+* Dev - Added woocommerce_ajax_order_items_removed hook. #29241
+* Dev - Fix usage of docker-compose (wc-e2e) commands in e2e tests when running them within WSL2. #29207
+* Dev - Fixes to documentation of WC_Shipping_Rate. #29117
+* Dev - Add tracks event when a user clicks on the links of the WooCommerce Status widget. #29109
+* Dev - Track the number of installations of WooCommerce Payments via that extensions banner for stores that have opted in to tracking. #29052
+* Dev - Added woocommerce_ajax_order_items_removed hook. #28936
+* Dev - Add tracking of woocommerce_admin_disabled usage. #28535
+* Enhancement - Add support for the low stock threshold for variations. #29345
+* Enhancement - Clean up of major version update compatibility warnings. #29200
+* Enhancement - Add a new dashboard widget to promote users to finish onboarding tasks. #29174
+* Enhancement - Update the Woo widget net sales link and logic to use the new analytics page and data. #29149
+* Enhancement - Added the body class woocommerce-shop to the shop page, so that it can be targeted via CSS. (#28724). #29051
+* Enhancement - Make sure downloadable file paths are properly recognized for strengthened security. #28699
+* Enhancement - Delay the registration of data exporters and erasers to avoid multiple language files from being loaded. #28078
+* Fix - Offsets not calculated correctly sometimes on select2 dropdowns causing usability issues. #29397
+* Fix - Handle errors in fault installations of PHP Intl. #29391
+* Fix - Cart page calculate shipping fields not showing correct fields based on location. #29282
+* Fix - Product categories widget item count not always showing the correct number. #29281
+* Fix - Updated include/rest-api/Controllers/Version3/class-wc-rest-shipping-zone-methods-controller.php to include a item schema function which appends support for order and class type values. #29218
+* Fix - Check if variation_id if belongs to the parent product while adding products to the cart. #29208
+* Fix - Reduce the number of ajax calls used when Geolocation (with Page Caching Enabled) mode is enabled. #29182
+* Fix - Don't display the coupon form on checkouts requiring the customer to be logged in to checkout. #29151
+* Fix - If coupon_lines are specified within a REST API order update, return an error if coupon item IDs are also specified. #29146
+* Fix - Avoids duplicating the word '(optional)' in the context of the Billing Address 2 field. #29136
+* Fix - PHP notice when checking out. #29133
+* Fix - Remove duplicate containers from the single and archive product pages. #29121
+* Fix - Wrong taxonomy caching in term and product attributes controllers. #29115
+* Fix - Make the parameters of the refund creation REST API behave as documented. #29099
+* Fix - Shipping methods with similar names could cause shipping method not selectable in order page. #29049
+* Fix - WC_Countries::get_formatted_address() not returning full name in correct order in some languages. #29008
+* Fix - add validation of the posted country codes on checkout. #28849
+* Fix - Correctly display pagination arrows on RTL languages. #28523
+* Fix - Invalid refund amount error on $0 refund when number of decimals is equal to 0. #27277
+* Fix - "Sale" badge misaligned on products when displaying 1 item per row. #29425
+* Fix - Revert a replacement of wp_redirect to wp_safe_redirect in WC_Checkout::process_order_payment that caused issues in the default PayPal interface. #29459
+* Fix - Don't remove existing coupons from order when an invalid REST API request for updating coupons is submitted. #29474
+* Fix - Wrong logic for including or excluding the payments step in the list of completed tasks in the onboarding wizard. #29518
+* Fix - Error when loading the admin dashboard while the admin package was disabled. #29613
+* Fix - "'' is not a valid country code" error when no billing/shipping country specified (e.g. when using PayPal checkout). #29606
+* Fix - Sanitize tax class and display errors in admin while creating tax classes.
+* Fix - Check if a verified product owner is required before placing a review.
+* Fix - Make product name escaping consistent in the front-end.
+* Tweak - Added the Mercado Pago logo into the assets/images folder in order to use it in the payments setup task. #29365
+* Tweak - Update the contributor guidelines. #29150
+* Tweak - Introduced phone number input validation. #27242
+* Tweak - Escape short description.
+* Update - WooCommerce Admin package 2.1.5. #29577
+* Update - WooCommerce Blocks package 4.7.0. #29406
+
+**WooCommerce Admin - 2.1.0 & 2.1.1 & 2.1.2 & 2.1.3 & 2.1.4 & 2.1.5**
+
+* Add - Add navigation intro modal. #6367
+* Add - CES track settings tab on updating settings #6368
+* Add - Core settings redirection to new settings pages #6091
+* Add - Favorites tooltip to the navigation #6312
+* Add - Favoriting extensions client UI #6287
+* Add - Remove CES actions for adding and editing a product and editing an order #6355
+* Add - Settings client pages #6092
+* Add - Settings feature and pages #6089
+* Dev - Add filter to allow enabling the WP toolbar within the new navigation. #6371
+* Dev - Add navigation favorites data store #6275
+* Dev - Add unit tests to Navigation's Container component. #6344
+* Dev - Allow highlight tooltip to use body tag as parent. #6309
+* Dev - Change `siteUrl` to `homeUrl` on navigation site title #6240
+* Dev - Fix the react state update error on homescreen. #6320
+* Dev - Refactor head and body heights #6247
+* Dev - Remove Google fonts and material icons. #6343
+* Dev - Use box sizing and padding to fix nav and admin menu styling #6335
+* Enhancement - Move capability checks to client #6365
+* Enhancement - Move favorited menu items to primary menu #6290
+* Enhancement - Navigation: Add test to container component #6344
+* Enhancement - override wpbody styles when nav present #6354
+* Feature - Increase target audience for business feature step. #6508
+* Fix - Add check for navigating being enabled. #6462
+* Fix - Add customer name column to CSV export #6556
+* Fix - Add guard to "Deactivate Plugin" note handlers to prevent fatal error. #6532
+* Fix - Adding New Zealand and Ireland to selective bundle option, previously missed. #6649
+* Fix - Broken link anchors to online documentation. #6455
+* Fix - Check if tax was successfully added before displaying notice #6229
+* Fix - Correct a bug where the JP connection flow would not happen when installing JP in the OBW. #6521
+* Fix - Crash of Analytics > Settings page when Gutenberg is installed. #6540
+* Fix - Display" option fails to collapse upon invoking "Help" option #6233
+* Fix - Email notes now are turned off by default #6324
+* Fix - Empty nav menu #6366
+* Fix - Enqueue scripts called incorrectly in php unit tests #6358
+* Fix - Hide tooltip in welcome modal #6142
+* Fix - Recommended Payment Banner missing in Safari #6375
+* Fix - Removal of core settings pages #6328
+* Fix - Removed @woocommerce/components/card from OBW #6374
+* Fix - Reset Navigation submenu before making Flyout #6396
+* Fix - Restore missing Correct the Klarna slug #6440
+* Fix - Top bar slightly overlaps wp-admin navigation on mobile #6292
+* Fix - update single column home screen width to 680px #6297
+* Fix - Update timing of InboxPanel state changes for the unread indicator #6246
+* Tweak - Enqueue beta features scripts on enqueue_scripts action instead of filter #6358
+* Tweak - Move admin menu manipulation from admin_head to admin_menu #6310
+* Tweak - Navigation: Migrate methods to `admin_menu` hook #6319
+* Tweak - New Settings: Turn off in dev mode #6348
+* Tweak - Order and styles updates to nav footer #6373
+* Tweak - Remove categories without menu items #6329
+* Tweak - Set international country feature flag off
+* Tweak - Set `is_deleted` from the database when instantiating a `Note` #6322
+* Tweak - Update inline documentation for navigation Screen class #6173
+* Tweak - Updates to copy and punctuation to be more conversational and consistent. #6298
+
+**WooCommerce Blocks - 4.5.0 & 4.6.0 & 4.7.0 & 4.7.1**
+
+* Enhancement - Login links on the checkout should use the account page. ([3844](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3844))
+* Enhancement - Prevent checkout linking to trashed terms and policy pages. ([3843](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3843))
+* Enhancement - Improved nonce logic by moving nonces to cart routes only. ([3812](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3812))
+* Enhancement - If coupons become invalid between applying to a cart and checking out, show the user a notice when the order is placed. ([3810](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3810))
+* Enhancement - Improve design of cart and checkout sidebars. ([3797](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3797))
+* Enhancement - Improve error displayed to customers when an item's stock status changes during checkout. ([3703](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3703))
+* Enhancement - Dev - Block Checkout will now respect custom address locales and custom country states via core filter hooks. ([3662](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3662))
+* Enhancement - Update checkout block payment methods UI. ([3439](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3439))
+* Enhancement - StoreAPI: Inject Order and Cart Controllers into Routes. ([3871](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3871))
+* Enhancement - Update Panel component class names to follow guidelines. More info can be found in our theming docs: https://github.com/woocommerce/woocommerce-gutenberg-products-block/blob/18dd54f07262b4d1dcf15561624617f824fcdc22/docs/theming/class-names-update-460.md. ([3860](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3860))
+* Enhancement - Refactor block type registration to support 3rd party integrations.
+* Enhancement - A new configuration property is available to registered payment methods for additional logic handling of saved payment method tokens. ([3961](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3961))
+* Enhancement - Provided billing data to payment method extensions so they can decide if payment is possible. ([3922](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3922))
+* Enhancement - Prevent errant payment methods from keeping Cart and Checkout blocks from loading. ([3920](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3920))
+* Fix block elements that don't play well with dark backgrounds. ([3887](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3887))
+* Fix - JS warning if two cart products share the same name. ([3814](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3814))
+* Fix - Align place order button to the right of the block. ([3803](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3803))
+* Fix - Ensure special characters are displayed properly in the Cart sidebar. ([3721](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3721))
+* Fix - Bug where the total price of items did not include tax in the cart and checkout blocks. ([3851](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3851))
+* Fix - Handle out-of-stock product visibility setting in All Products block. ([3859](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3859))
+* Fix - Show cart item subtotal instead of total in Cart and Checkout blocks ([#3905](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3905))
+* Fix - Fix button styles in Twenty Nineteen theme. ([3862](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3862))
+* Fix - Return correct sale/regular prices for variable products in the Store API. ([3854](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3854))
+* Fix - Remove shadows from text buttons and gradient background from selects in some themes. ([3846](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3846))
+* Fix - Hide Browse Shop link in cart block empty state when there is no shop page. ([3845](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3845))
+* Fix - Remove extra padding from payment methods with no description. ([3952](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3952))
+* Fix - "save payment" checkbox not showing for payment methods. ([3950](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3950))
+* Fix - Cart preview when shipping rates are set to be hidden until an address is entered. ([3946](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3946))
+* Fix - Sync cart item quantity if its Implicitly changed. ([3907](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3907))
+* Fix - FSE not being visible when WC Blocks was enabled. ([3898](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3898))
+* Fix - Ensure sale badges have a uniform height in the Cart block. ([3897](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3897))
+* Note - Internally, this release has modified how `AbstractBlock` (the base class for all of our blocks) functions, and how it loads assets. `AbstractBlock` is internal to this project and does not seem like something that would ever need to be extended by 3rd parties, but note if you are doing so for whatever reason, your implementation would need to be updated to match. ([3829](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3829))
+
+= 5.1.0 2021-03-09 =
+
+**WooCommerce**
+
+* Update - WooCommerce Admin package 2.0.2. #29229
+* Update - WooCommerce Blocks package 4.4.3. #29016
+* Fix - Error in notice message of reports when WC Admin is disabled via a filter. #29095
+* Fix - Error when calculating orders with tax option rounding at subtotal level in PHP 8. #29089
+* Fix - price filtering not working properly with variable products whose variations have different prices. #29043
+* Fix - Removed extra closing brace from the Zone regions help text. #29036
+* Fix - Tax name/label is not being updated in the order when it is changed. #28983
+* Fix - Additional protection after wc_get_product to account for invalid ID. #28962
+* Fix - orders list from returning false values if orders are missing. #28927
+* Fix - Terms and Policy checkbox wording settings not shown in customizer. #28735
+* Fix - Admin notices sometimes were persisting even after dismissing. #28500
+* Fix - Calculate discount based on order location in the admin view. #26983
+* Fix - SASS variables not being compile correctly due to recent SASS version. #29120
+* Fix - Placeholder image height in cart. #29139
+* Dev - Updated admin bar icons to use SVG and Dashicons instead of custom font. #29094
+* Dev - Admin menu modification has been moved from admin_head hooks to admin_menu hooks. #29088
+* Dev - status report generation time to the Status Report. #28980
+* Dev - Add the 'woocommerce_exporter_product_types' filter to allow third-parties to filter the product types which can be imported and exported. #28950
+* Dev - Filter added to allow 'woocommerce_hold_stock_minutes' to be customized. #28933
+* Dev - Add optional semicolon to JS code for better compatibility. #28880
+* Dev - Added Guatemala states. #28755
+* Dev - jQuery 3 deprecated functions update. #28753
+* Dev - Add Woo Version as global prop in track events. #28627
+* Dev - Added orders count by payment method to Tracker data and replaced direct DB calls with CRUD. #28584
+* Dev - WC_Tax::get_tax_rate_classes() is now public. #27671
+* Dev - "Store management insights" option now is turned off by default. #29105
+* Dev - Update the woo widget stock links to the new analytics page. #29093
+* Tweak - Updated WooCommerce logo color. #29054
+* Tweak - Correctly aligns content in the checkout with Twenty Twenty-One. #28951
+* Tweak - Use assigned variable for $post_thumbnail_id instead of calling function more than once. #28919
+* Tweak - Ensure that all tracker values collected for orders are of string type. #28893
+* Tweak - Adjust CSS font size and spacing for Twenty Twenty One. #28827
+
+**WooCommerce Admin - 2.0.0 & 2.0.1 & 2.0.2**
+
+* Tweak - Bump minimum supported version of PHP to 7.0. #6046
+* Tweak - update the content and timing of the NeedSomeInspiration note. #6076
+* Tweak - Adjust the Marketing note not to show until store is at least 5 days. #6083
+* Tweak - Refactored extended task list. #6081
+* Fix - Add support for a floating-point number as a SummaryNumber's delta. #5926
+* Fix - allow for more terms to be shown for product attributes in the Analytics orders report. #5868
+* Fix - Fixed the Add First Product email note checks. #6260
+* Fix - Onboarding - Fixed "Business Details" error. #6271
+* Fix - Show management links when only main task list is hidden. #6291
+* Fix - Correct the Klarna slug. #6440
+* Add - new inbox message - Getting started in Ecommerce - watch this webinar. #6086
+* Add - Remote inbox notifications contains comparison and fix product rule. #6073
+* Add - Task list payments - include Mollie as an option. #6257
+* Update - store deprecation welcome modal support doc link #6094
+* Update - Homescreen layout, moving Inbox panel for better interaction. #6122
+* Enhancement - Allowing users to create products by selecting a template. #5892
+* Enhancement - Use the new Paypal payments plugin for onboarding. #6261
+* Dev - Add wait script for mysql to be ready for phpunit tests in docker. #6185
+* Dev - Remove old debug code for connecting to Calypso / Wordpress.com. #6097
+* Dev - Allow highlight tooltip to use body tag as parent. #6309
+
+**WooCommerce Blocks - 4.1.0 & 4.2.0 & 4.3.0 & 4.4.0 & 4.4.1 & 4.4.2 & 4.4.3**
+
+* Update - Jetpack Autoloader to 2.9.1.
+* Update - Update package for WooCommerce core inclusion.
+* Enhancements - Design tweaks to the cart page which move the quantity picker below each cart item and improve usability on mobile. ([3734](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3734))
+* Enhancements - Store API - Fix selected rate in cart shipping rates response. ([3680](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3680))
+* Enhancements - Create get_item_responses_from_schema abstraction. ([3679](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3679))
+* Enhancements - Show itemized fee rows in the cart/checkout blocks. ([3678](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3678))
+* Enhancements - Extensibility: Show item data in Cart and Checkout blocks and update the variation data styles. ([3665](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3665))
+* Enhancements - Introduce SlotFill for Sidebar. ([3361](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3361))
+* Enhancements - Add the ability to directly upload an image in Featured Category and Featured Product blocks. ([3579](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3579))
+* Enhancements - Fix coupon code button height not adapting to the font size. ([3575](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3575))
+* Enhancements - Fixed Coupon Code panel not expanding/contracting in some themes. ([3569](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3569))
+* Enhancements - Fix: Added fallback styling for screen reader text. ([3557](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3557))
+* Fix - Ensure empty categories are correctly hidden in the product categories block. ([3765](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3765))
+* Fix - Added missing wrapper div within FeaturedCategory and FeatureProduct blocks. ([3746](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3746))
+* Fix - Set correct text color in BlockErrorBoundry notices. ([3738](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3738))
+* Fix - Hidden cart item meta data will not be rendered in the Cart and Checkout blocks. ([3732](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3732))
+* Fix - Improved accessibility of product image links in the products block by using correct aria tags and hiding empty image placeholders. ([3722](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3722))
+* Fix - Add missing aria-label for stars image in the review-list-item component. ([3706](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3706))
+* Fix - Prevent "X-WC-Store-API-Nonce is invalid" error when going back to a page with the products block using the browser back button. ([3770](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3770))
+* Fix - Adds a default "features" array for payment methods which do not define supported features. Fixes conflicts with 3rd Party payment method integrations.
+* Fix - Fix an error that was blocking checkout with some user saved payment methods. ([3627](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3627))
+* Fix - Fix nonce issues when adding product to cart from All Products. ([3598](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3598))
+* Fix - Fix bug inside Product Search in the editor. ([3578](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3578))
+* Fix - Fix console warnings in WordPress 5.6. ([3577](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3577))
+* Fix - Fixed text visibility in select inputs when using Twenty Twenty-One theme's dark mode. ([3554](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3554))
+* Fix - Fix product list images skewed in Widgets editor. ([3553](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3553))
+* Add address validation to values posted to the Checkout via StoreApi. ([3552](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3552))
+* Fix - Fix Fees not visible in Cart & Checkout blocks when order doesn't need shipping. ([3521](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3521))
+* Fix - Fix All Products block edit screen. ([3547](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3547))
+* Fix - Checkout block: Prevent `Create an account` from creating up a user account if the order fails coupon validation. ([3423](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3423))
+* Fix - Make sure cart is initialized before the CartItems route is used in the Store API. ([3488](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3488))
+* Fix - Fix notice close button color in Twenty Twenty One dark mode. ([3472](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3472))
+* Fix - Remove held stock for a draft order if an item is removed from the cart. ([3468](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3468))
+* Fix - Ensure correct alignment of checkout notice's dismiss button. ([3455](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3455))
+* Fix - Fixed a bug in Checkout block (Store API) causing checkout to fail when using an invalid coupon and creating an account.
+* Fix - Checkout block: Correctly handle cases where the order fails with an error (e.g. invalid coupon) and a new user account is created. ([3429](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3429))
+* Update - Hide the All Products Block from the new Gutenberg Widget Areas until full support is achieved. ([3737](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3737))
+* Update - Legacy `star-rating` class name has been removed from Product rating block (inside All Products block). That element is still selectable with the `.wc-block-components-product-rating` class name. ([3717](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3717))
+* Update - Update input colors and alignment. ([3597](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3597))
+* Update - Removed compatibility with packages in WordPress 5.3. ([3541](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3541))
+* Update - Bumped the minimum WP required version to 5.4. ([3537](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3537))
+* Dev - Change register_endpoint_data to use an array of params instead of individual params. ([3478](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3478))
+* Dev - Expose store/cart via ExtendRestApi to extensions. ([3445](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3445))
+* Dev - Added formatting classes to the Store API for extensions to consume.
+* Dev - Refactored and reordered Store API checkout processing to handle various edge cases and better support future extensibility. ([3454](https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3454))
+
= 5.0.0 - 2021-02-09 =
**WooCommerce**
@@ -1099,6 +1370,7 @@
* Fix - Don't show duplicated update notifications on Woo Screens. #25828
* Fix - Escape MaxMind database URL. #25682
* Fix - System status report should correctly identify inactive package. #25830
+* Fix - "Sale" badge misaligned on products when displaying 1 item per row. #29425
* Dev - Added support for placeholder attribute in quantity inputs. #25418
* Dev - Added `tax_status` and `tax_class` columns to the product meta data lookup table. #25428
* Dev - Introduced `woocommerce_top_rated_widget_args` filter. #25320
diff --git a/composer.json b/composer.json
index 33cecfc6758..10c9be56a53 100644
--- a/composer.json
+++ b/composer.json
@@ -14,15 +14,15 @@
],
"require": {
"php": ">=7.0",
- "automattic/jetpack-autoloader": "2.9.1",
+ "automattic/jetpack-autoloader": "2.10.1",
"automattic/jetpack-constants": "1.5.1",
"composer/installers": "~1.7",
"maxmind-db/reader": "1.6.0",
"pelago/emogrifier": "3.1.0",
"psr/container": "1.0.0",
"woocommerce/action-scheduler": "3.1.6",
- "woocommerce/woocommerce-admin": "2.0.2",
- "woocommerce/woocommerce-blocks": "4.4.3"
+ "woocommerce/woocommerce-admin": "2.2.2-rc.1",
+ "woocommerce/woocommerce-blocks": "4.9.1"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.4"
diff --git a/composer.lock b/composer.lock
index 24b5bc27a02..e74cb27df92 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,32 +4,39 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "f24a600ea103061d766dd7b06c13e8f2",
+ "content-hash": "be33d948ed1d2ee3a7a23ef657f3148d",
"packages": [
{
"name": "automattic/jetpack-autoloader",
- "version": "v2.9.1",
+ "version": "2.10.1",
"source": {
"type": "git",
"url": "https://github.com/Automattic/jetpack-autoloader.git",
- "reference": "d6ca2cc26ad6963e1be19b3338a9e98f40d9bd88"
+ "reference": "20393c4677765c3e737dcb5aee7a3f7b90dce4b3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/d6ca2cc26ad6963e1be19b3338a9e98f40d9bd88",
- "reference": "d6ca2cc26ad6963e1be19b3338a9e98f40d9bd88",
+ "url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/20393c4677765c3e737dcb5aee7a3f7b90dce4b3",
+ "reference": "20393c4677765c3e737dcb5aee7a3f7b90dce4b3",
"shasum": ""
},
"require": {
"composer-plugin-api": "^1.1 || ^2.0"
},
"require-dev": {
+ "automattic/jetpack-changelogger": "^1.1",
"yoast/phpunit-polyfills": "0.2.0"
},
"type": "composer-plugin",
"extra": {
"class": "Automattic\\Jetpack\\Autoloader\\CustomAutoloaderPlugin",
- "mirror-repo": "Automattic/jetpack-autoloader"
+ "mirror-repo": "Automattic/jetpack-autoloader",
+ "changelogger": {
+ "link-template": "https://github.com/Automattic/jetpack-autoloader/compare/v${old}...v${new}"
+ },
+ "branch-alias": {
+ "dev-master": "2.10.x-dev"
+ }
},
"autoload": {
"classmap": [
@@ -44,10 +51,7 @@
"GPL-2.0-or-later"
],
"description": "Creates a custom autoloader for a plugin or theme.",
- "support": {
- "source": "https://github.com/Automattic/jetpack-autoloader/tree/v2.9.1"
- },
- "time": "2021-02-05T19:07:06+00:00"
+ "time": "2021-03-30T15:15:59+00:00"
},
{
"name": "automattic/jetpack-constants",
@@ -78,23 +82,20 @@
"GPL-2.0-or-later"
],
"description": "A wrapper for defining constants in a more testable way.",
- "support": {
- "source": "https://github.com/Automattic/jetpack-constants/tree/v1.5.1"
- },
"time": "2020-10-28T19:00:31+00:00"
},
{
"name": "composer/installers",
- "version": "v1.10.0",
+ "version": "v1.11.0",
"source": {
"type": "git",
"url": "https://github.com/composer/installers.git",
- "reference": "1a0357fccad9d1cc1ea0c9a05b8847fbccccb78d"
+ "reference": "ae03311f45dfe194412081526be2e003960df74b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/installers/zipball/1a0357fccad9d1cc1ea0c9a05b8847fbccccb78d",
- "reference": "1a0357fccad9d1cc1ea0c9a05b8847fbccccb78d",
+ "url": "https://api.github.com/repos/composer/installers/zipball/ae03311f45dfe194412081526be2e003960df74b",
+ "reference": "ae03311f45dfe194412081526be2e003960df74b",
"shasum": ""
},
"require": {
@@ -188,6 +189,7 @@
"majima",
"mako",
"mediawiki",
+ "miaoxing",
"modulework",
"modx",
"moodle",
@@ -205,16 +207,13 @@
"sydes",
"sylius",
"symfony",
+ "tastyigniter",
"typo3",
"wordpress",
"yawik",
"zend",
"zikula"
],
- "support": {
- "issues": "https://github.com/composer/installers/issues",
- "source": "https://github.com/composer/installers/tree/v1.10.0"
- },
"funding": [
{
"url": "https://packagist.com",
@@ -229,7 +228,7 @@
"type": "tidelift"
}
],
- "time": "2021-01-14T11:07:16+00:00"
+ "time": "2021-04-28T06:42:17+00:00"
},
{
"name": "maxmind-db/reader",
@@ -289,10 +288,6 @@
"geolocation",
"maxmind"
],
- "support": {
- "issues": "https://github.com/maxmind/MaxMind-DB-Reader-php/issues",
- "source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.6.0"
- },
"time": "2019-12-19T22:59:03+00:00"
},
{
@@ -367,10 +362,6 @@
"email",
"pre-processing"
],
- "support": {
- "issues": "https://github.com/MyIntervals/emogrifier/issues",
- "source": "https://github.com/MyIntervals/emogrifier"
- },
"time": "2019-12-26T19:37:31+00:00"
},
{
@@ -420,10 +411,6 @@
"container-interop",
"psr"
],
- "support": {
- "issues": "https://github.com/php-fig/container/issues",
- "source": "https://github.com/php-fig/container/tree/master"
- },
"time": "2017-02-14T16:28:37+00:00"
},
{
@@ -477,9 +464,6 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
- "support": {
- "source": "https://github.com/symfony/css-selector/tree/master"
- },
"time": "2017-05-01T15:01:29+00:00"
},
{
@@ -515,24 +499,20 @@
],
"description": "Action Scheduler for WordPress and WooCommerce",
"homepage": "https://actionscheduler.org/",
- "support": {
- "issues": "https://github.com/woocommerce/action-scheduler/issues",
- "source": "https://github.com/woocommerce/action-scheduler/tree/master"
- },
"time": "2020-05-12T16:22:33+00:00"
},
{
"name": "woocommerce/woocommerce-admin",
- "version": "2.0.2",
+ "version": "2.2.2-rc.1",
"source": {
"type": "git",
"url": "https://github.com/woocommerce/woocommerce-admin.git",
- "reference": "c4ffd90ebc72652f9d1bc8943a56d7723acc5bf4"
+ "reference": "0d305d1716481a0cc2010ec7b0a608a2d3c8ebe4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/c4ffd90ebc72652f9d1bc8943a56d7723acc5bf4",
- "reference": "c4ffd90ebc72652f9d1bc8943a56d7723acc5bf4",
+ "url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/0d305d1716481a0cc2010ec7b0a608a2d3c8ebe4",
+ "reference": "0d305d1716481a0cc2010ec7b0a608a2d3c8ebe4",
"shasum": ""
},
"require": {
@@ -564,24 +544,20 @@
],
"description": "A modern, javascript-driven WooCommerce Admin experience.",
"homepage": "https://github.com/woocommerce/woocommerce-admin",
- "support": {
- "issues": "https://github.com/woocommerce/woocommerce-admin/issues",
- "source": "https://github.com/woocommerce/woocommerce-admin/tree/v2.0.2"
- },
- "time": "2021-02-25T07:29:24+00:00"
+ "time": "2021-04-28T19:39:33+00:00"
},
{
"name": "woocommerce/woocommerce-blocks",
- "version": "v4.4.3",
+ "version": "v4.9.1",
"source": {
"type": "git",
"url": "https://github.com/woocommerce/woocommerce-gutenberg-products-block.git",
- "reference": "1eade21846e81d5aaf9bf40cdd1be60778849244"
+ "reference": "62f32bfb45dfcb2ba3ca349a6ed0a8cf48ddefce"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/woocommerce/woocommerce-gutenberg-products-block/zipball/1eade21846e81d5aaf9bf40cdd1be60778849244",
- "reference": "1eade21846e81d5aaf9bf40cdd1be60778849244",
+ "url": "https://api.github.com/repos/woocommerce/woocommerce-gutenberg-products-block/zipball/62f32bfb45dfcb2ba3ca349a6ed0a8cf48ddefce",
+ "reference": "62f32bfb45dfcb2ba3ca349a6ed0a8cf48ddefce",
"shasum": ""
},
"require": {
@@ -615,11 +591,7 @@
"gutenberg",
"woocommerce"
],
- "support": {
- "issues": "https://github.com/woocommerce/woocommerce-gutenberg-products-block/issues",
- "source": "https://github.com/woocommerce/woocommerce-gutenberg-products-block/tree/v4.4.3"
- },
- "time": "2021-02-11T18:07:48+00:00"
+ "time": "2021-04-13T16:11:16+00:00"
}
],
"packages-dev": [
@@ -667,10 +639,6 @@
"isolation",
"tool"
],
- "support": {
- "issues": "https://github.com/bamarni/composer-bin-plugin/issues",
- "source": "https://github.com/bamarni/composer-bin-plugin/tree/master"
- },
"time": "2020-05-03T08:27:20+00:00"
}
],
@@ -686,5 +654,5 @@
"platform-overrides": {
"php": "7.0"
},
- "plugin-api-version": "2.0.0"
+ "plugin-api-version": "1.1.0"
}
diff --git a/includes/abstracts/abstract-wc-order.php b/includes/abstracts/abstract-wc-order.php
index 4c282a8cc03..e07153da6e7 100644
--- a/includes/abstracts/abstract-wc-order.php
+++ b/includes/abstracts/abstract-wc-order.php
@@ -1633,6 +1633,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
continue;
}
$saved_rate_ids[] = $tax->get_rate_id();
+ $tax->set_rate( $tax->get_rate_id() );
$tax->set_tax_total( isset( $cart_taxes[ $tax->get_rate_id() ] ) ? $cart_taxes[ $tax->get_rate_id() ] : 0 );
$tax->set_label( WC_Tax::get_rate_label( $tax->get_rate_id() ) );
$tax->set_shipping_tax_total( ! empty( $shipping_taxes[ $tax->get_rate_id() ] ) ? $shipping_taxes[ $tax->get_rate_id() ] : 0 );
diff --git a/includes/abstracts/abstract-wc-payment-gateway.php b/includes/abstracts/abstract-wc-payment-gateway.php
index fe29740e569..3dcc281464d 100644
--- a/includes/abstracts/abstract-wc-payment-gateway.php
+++ b/includes/abstracts/abstract-wc-payment-gateway.php
@@ -262,7 +262,9 @@ abstract class WC_Payment_Gateway extends WC_Settings_API {
// Gets order total from "pay for order" page.
if ( 0 < $order_id ) {
$order = wc_get_order( $order_id );
- $total = (float) $order->get_total();
+ if ( $order ) {
+ $total = (float) $order->get_total();
+ }
// Gets order total from cart/checkout.
} elseif ( 0 < WC()->cart->total ) {
diff --git a/includes/abstracts/abstract-wc-settings-api.php b/includes/abstracts/abstract-wc-settings-api.php
index f33a62365fc..35bdbe522b7 100644
--- a/includes/abstracts/abstract-wc-settings-api.php
+++ b/includes/abstracts/abstract-wc-settings-api.php
@@ -696,6 +696,7 @@ abstract class WC_Settings_API {
);
$data = wp_parse_args( $data, $defaults );
+ $value = $this->get_option( $key );
ob_start();
?>
@@ -708,7 +709,15 @@ abstract class WC_Settings_API {
get_description_html( $data ); // WPCS: XSS ok. ?>
diff --git a/includes/admin/class-wc-admin-assets.php b/includes/admin/class-wc-admin-assets.php
index 567e2efe7ca..01e62199ba5 100644
--- a/includes/admin/class-wc-admin-assets.php
+++ b/includes/admin/class-wc-admin-assets.php
@@ -145,6 +145,7 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
'search_products_nonce' => wp_create_nonce( 'search-products' ),
'search_customers_nonce' => wp_create_nonce( 'search-customers' ),
'search_categories_nonce' => wp_create_nonce( 'search-categories' ),
+ 'search_pages_nonce' => wp_create_nonce( 'search-pages' ),
)
);
diff --git a/includes/admin/class-wc-admin-dashboard-setup.php b/includes/admin/class-wc-admin-dashboard-setup.php
index 8fdbc1e94de..4360241b37f 100644
--- a/includes/admin/class-wc-admin-dashboard-setup.php
+++ b/includes/admin/class-wc-admin-dashboard-setup.php
@@ -162,7 +162,9 @@ if ( ! class_exists( 'WC_Admin_Dashboard_Setup', false ) ) :
* @return bool
*/
private function should_display_widget() {
- return 'yes' !== get_option( 'woocommerce_task_list_complete' ) && 'yes' !== get_option( 'woocommerce_task_list_hidden' );
+ return WC()->is_wc_admin_active() &&
+ 'yes' !== get_option( 'woocommerce_task_list_complete' ) &&
+ 'yes' !== get_option( 'woocommerce_task_list_hidden' );
}
/**
@@ -170,7 +172,7 @@ if ( ! class_exists( 'WC_Admin_Dashboard_Setup', false ) ) :
*/
private function populate_payment_tasks() {
$is_woo_payment_installed = is_plugin_active( 'woocommerce-payments/woocommerce-payments.php' );
- $country = explode( ':', get_option( 'woocommerce_default_country', '' ) )[0];
+ $country = explode( ':', get_option( 'woocommerce_default_country', 'US:CA' ) )[0];
// woocommerce-payments requires its plugin activated and country must be US.
if ( ! $is_woo_payment_installed || 'US' !== $country ) {
@@ -178,7 +180,7 @@ if ( ! class_exists( 'WC_Admin_Dashboard_Setup', false ) ) :
}
// payments can't be used when woocommerce-payments exists and country is US.
- if ( $is_woo_payment_installed || 'US' === $country ) {
+ if ( $is_woo_payment_installed && 'US' === $country ) {
unset( $this->tasks['payments'] );
}
diff --git a/includes/admin/class-wc-admin-dashboard.php b/includes/admin/class-wc-admin-dashboard.php
index 498eeee78ae..6357b46e8bd 100644
--- a/includes/admin/class-wc-admin-dashboard.php
+++ b/includes/admin/class-wc-admin-dashboard.php
@@ -63,6 +63,10 @@ if ( ! class_exists( 'WC_Admin_Dashboard', false ) ) :
* @return bool
*/
private function should_display_widget() {
+ if ( ! WC()->is_wc_admin_active() ) {
+ return false;
+ }
+
$has_permission = current_user_can( 'view_woocommerce_reports' ) || current_user_can( 'manage_woocommerce' ) || current_user_can( 'publish_shop_orders' );
$task_completed_or_hidden = 'yes' === get_option( 'woocommerce_task_list_complete' ) || 'yes' === get_option( 'woocommerce_task_list_hidden' );
return $task_completed_or_hidden && $has_permission;
@@ -127,11 +131,11 @@ if ( ! class_exists( 'WC_Admin_Dashboard', false ) ) :
$reports = new WC_Admin_Report();
- $net_sales_link = 'admin.php?page=wc-reports&tab=orders&range=month';
+ $net_sales_link = 'admin.php?page=wc-reports&tab=orders&range=month';
$top_seller_link = 'admin.php?page=wc-reports&tab=orders&report=sales_by_product&range=month&product_ids=';
- $report_data = $is_wc_admin_disabled ? $this->get_sales_report_data() : $this->get_wc_admin_performance_data();
+ $report_data = $is_wc_admin_disabled ? $this->get_sales_report_data() : $this->get_wc_admin_performance_data();
if ( ! $is_wc_admin_disabled ) {
- $net_sales_link = 'admin.php?page=wc-admin&path=%2Fanalytics%2Frevenue&chart=net_revenue&orderby=net_revenue&period=month&compare=previous_period';
+ $net_sales_link = 'admin.php?page=wc-admin&path=%2Fanalytics%2Frevenue&chart=net_revenue&orderby=net_revenue&period=month&compare=previous_period';
$top_seller_link = 'admin.php?page=wc-admin&filter=single_product&path=%2Fanalytics%2Fproducts&products=';
}
diff --git a/includes/admin/class-wc-admin-post-types.php b/includes/admin/class-wc-admin-post-types.php
index e2d145206a1..2eaef024a14 100644
--- a/includes/admin/class-wc-admin-post-types.php
+++ b/includes/admin/class-wc-admin-post-types.php
@@ -430,7 +430,10 @@ class WC_Admin_Post_Types {
// phpcs:enable WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$product->set_manage_stock( $manage_stock );
- $product->set_backorders( $backorders );
+
+ if ( 'external' !== $product->get_type() ) {
+ $product->set_backorders( $backorders );
+ }
if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) {
$stock_amount = 'yes' === $manage_stock && isset( $request_data['_stock'] ) && is_numeric( wp_unslash( $request_data['_stock'] ) ) ? wc_stock_amount( wp_unslash( $request_data['_stock'] ) ) : '';
@@ -550,7 +553,10 @@ class WC_Admin_Post_Types {
$stock_amount = 'yes' === $manage_stock && ! empty( $request_data['change_stock'] ) && isset( $request_data['_stock'] ) ? wc_stock_amount( $request_data['_stock'] ) : $product->get_stock_quantity();
$product->set_manage_stock( $manage_stock );
- $product->set_backorders( $backorders );
+
+ if ( 'external' !== $product->get_type() ) {
+ $product->set_backorders( $backorders );
+ }
if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) {
$change_stock = absint( $request_data['change_stock'] );
diff --git a/includes/admin/class-wc-admin-settings.php b/includes/admin/class-wc-admin-settings.php
index b36d9a889d6..69506066749 100644
--- a/includes/admin/class-wc-admin-settings.php
+++ b/includes/admin/class-wc-admin-settings.php
@@ -579,6 +579,47 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
post_title,
+ $option_value
+ );
+ }
+ ?>
+