|
| 1 | +diff --git a/vendor/magento/module-search/ViewModel/ConfigProvider.php b/vendor/magento/module-search/ViewModel/ConfigProvider.php |
| 2 | +index be3366e62e9..b1db5b57e13 100644 |
| 3 | +--- a/vendor/magento/module-search/ViewModel/ConfigProvider.php |
| 4 | ++++ b/vendor/magento/module-search/ViewModel/ConfigProvider.php |
| 5 | +@@ -10,6 +10,7 @@ namespace Magento\Search\ViewModel; |
| 6 | + use Magento\Framework\App\Config\ScopeConfigInterface; |
| 7 | + use Magento\Framework\View\Element\Block\ArgumentInterface; |
| 8 | + use Magento\Store\Model\ScopeInterface; |
| 9 | ++use Magento\Search\Helper\Data as SearchHelper; |
| 10 | + |
| 11 | + /** |
| 12 | + * View model for search |
| 13 | +@@ -26,13 +27,31 @@ class ConfigProvider implements ArgumentInterface |
| 14 | + */ |
| 15 | + private $scopeConfig; |
| 16 | + |
| 17 | ++ /** |
| 18 | ++ * @var SearchHelper |
| 19 | ++ */ |
| 20 | ++ private $searchHelper; |
| 21 | ++ |
| 22 | + /** |
| 23 | + * @param ScopeConfigInterface $scopeConfig |
| 24 | ++ * @param SearchHelper $searchHelper |
| 25 | + */ |
| 26 | + public function __construct( |
| 27 | +- ScopeConfigInterface $scopeConfig |
| 28 | ++ ScopeConfigInterface $scopeConfig, |
| 29 | ++ SearchHelper $searchHelper |
| 30 | + ) { |
| 31 | + $this->scopeConfig = $scopeConfig; |
| 32 | ++ $this->searchHelper = $searchHelper; |
| 33 | ++ } |
| 34 | ++ |
| 35 | ++ /** |
| 36 | ++ * Retrieve search helper instance for template view |
| 37 | ++ * |
| 38 | ++ * @return SearchHelper |
| 39 | ++ */ |
| 40 | ++ public function getSearchHelperData(): SearchHelper |
| 41 | ++ { |
| 42 | ++ return $this->searchHelper; |
| 43 | + } |
| 44 | + |
| 45 | + /** |
| 46 | +diff --git a/vendor/magento/module-search/view/frontend/templates/form.mini.phtml b/vendor/magento/module-search/view/frontend/templates/form.mini.phtml |
| 47 | +index 80e720e2c2f..c6b2a6a7295 100644 |
| 48 | +--- a/vendor/magento/module-search/view/frontend/templates/form.mini.phtml |
| 49 | ++++ b/vendor/magento/module-search/view/frontend/templates/form.mini.phtml |
| 50 | +@@ -4,40 +4,42 @@ |
| 51 | + * See COPYING.txt for license details. |
| 52 | + */ |
| 53 | + |
| 54 | +-// phpcs:disable Magento2.Templates.ThisInTemplate.FoundThis |
| 55 | + ?> |
| 56 | + <?php |
| 57 | + /** @var $block \Magento\Framework\View\Element\Template */ |
| 58 | +-/** @var $helper \Magento\Search\Helper\Data */ |
| 59 | ++/** @var $escaper \Magento\Framework\Escaper */ |
| 60 | + /** @var $configProvider \Magento\Search\ViewModel\ConfigProvider */ |
| 61 | +-$helper = $this->helper(\Magento\Search\Helper\Data::class); |
| 62 | + $configProvider = $block->getData('configProvider'); |
| 63 | ++/** @var $helper \Magento\Search\Helper\Data */ |
| 64 | ++$helper = $configProvider->getSearchHelperData(); |
| 65 | ++$allowedSuggestion = $configProvider->isSuggestionsAllowed(); |
| 66 | ++$quickSearchUrl = $allowedSuggestion ? $escaper->escapeUrl($helper->getSuggestUrl()) : ''; |
| 67 | + ?> |
| 68 | + <div class="block block-search"> |
| 69 | +- <div class="block block-title"><strong><?= $block->escapeHtml(__('Search')) ?></strong></div> |
| 70 | ++ <div class="block block-title"><strong><?= $escaper->escapeHtml(__('Search')) ?></strong></div> |
| 71 | + <div class="block block-content"> |
| 72 | + <form class="form minisearch" id="search_mini_form" |
| 73 | +- action="<?= $block->escapeUrl($helper->getResultUrl()) ?>" method="get"> |
| 74 | ++ action="<?= $escaper->escapeUrl($helper->getResultUrl()) ?>" method="get"> |
| 75 | + <div class="field search"> |
| 76 | + <label class="label" for="search" data-role="minisearch-label"> |
| 77 | +- <span><?= $block->escapeHtml(__('Search')) ?></span> |
| 78 | ++ <span><?= $escaper->escapeHtml(__('Search')) ?></span> |
| 79 | + </label> |
| 80 | + <div class="control"> |
| 81 | + <input id="search" |
| 82 | +- <?php if ($configProvider->isSuggestionsAllowed()):?> |
| 83 | +- data-mage-init='{"quickSearch":{ |
| 84 | +- "formSelector":"#search_mini_form", |
| 85 | +- "url":"<?= $block->escapeUrl($helper->getSuggestUrl())?>", |
| 86 | +- "destinationSelector":"#search_autocomplete", |
| 87 | +- "minSearchLength":"<?= $block->escapeHtml($helper->getMinQueryLength()) ?>"} |
| 88 | +- }' |
| 89 | +- <?php endif;?> |
| 90 | ++ data-mage-init='{ |
| 91 | ++ "quickSearch": { |
| 92 | ++ "formSelector": "#search_mini_form", |
| 93 | ++ "url": "<?= /* @noEscape */ $quickSearchUrl ?>", |
| 94 | ++ "destinationSelector": "#search_autocomplete", |
| 95 | ++ "minSearchLength": "<?= $escaper->escapeHtml($helper->getMinQueryLength()) ?>" |
| 96 | ++ } |
| 97 | ++ }' |
| 98 | + type="text" |
| 99 | +- name="<?= $block->escapeHtmlAttr($helper->getQueryParamName()) ?>" |
| 100 | ++ name="<?= $escaper->escapeHtmlAttr($helper->getQueryParamName()) ?>" |
| 101 | + value="<?= /* @noEscape */ $helper->getEscapedQueryText() ?>" |
| 102 | +- placeholder="<?= $block->escapeHtmlAttr(__('Search entire store here...')) ?>" |
| 103 | ++ placeholder="<?= $escaper->escapeHtmlAttr(__('Search entire store here...')) ?>" |
| 104 | + class="input-text" |
| 105 | +- maxlength="<?= $block->escapeHtmlAttr($helper->getMaxQueryLength()) ?>" |
| 106 | ++ maxlength="<?= $escaper->escapeHtmlAttr($helper->getMaxQueryLength()) ?>" |
| 107 | + role="combobox" |
| 108 | + aria-haspopup="false" |
| 109 | + aria-autocomplete="both" |
| 110 | +@@ -49,11 +51,11 @@ $configProvider = $block->getData('configProvider'); |
| 111 | + </div> |
| 112 | + <div class="actions"> |
| 113 | + <button type="submit" |
| 114 | +- title="<?= $block->escapeHtml(__('Search')) ?>" |
| 115 | +- class="action search" |
| 116 | +- aria-label="Search" |
| 117 | ++ title="<?= $escaper->escapeHtml(__('Search')) ?>" |
| 118 | ++ class="action search" |
| 119 | ++ aria-label="Search" |
| 120 | + > |
| 121 | +- <span><?= $block->escapeHtml(__('Search')) ?></span> |
| 122 | ++ <span><?= $escaper->escapeHtml(__('Search')) ?></span> |
| 123 | + </button> |
| 124 | + </div> |
| 125 | + </form> |
| 126 | +diff --git a/vendor/magento/module-search/view/frontend/web/js/form-mini.js b/vendor/magento/module-search/view/frontend/web/js/form-mini.js |
| 127 | +index b4493c5f380..605c2fbbf9b 100644 |
| 128 | +--- a/vendor/magento/module-search/view/frontend/web/js/form-mini.js |
| 129 | ++++ b/vendor/magento/module-search/view/frontend/web/js/form-mini.js |
| 130 | +@@ -35,12 +35,12 @@ define([ |
| 131 | + selectClass: 'selected', |
| 132 | + template: |
| 133 | + '<li class="<%- data.row_class %>" id="qs-option-<%- data.index %>" role="option">' + |
| 134 | +- '<span class="qs-option-name">' + |
| 135 | +- ' <%- data.title %>' + |
| 136 | +- '</span>' + |
| 137 | +- '<span aria-hidden="true" class="amount">' + |
| 138 | +- '<%- data.num_results %>' + |
| 139 | +- '</span>' + |
| 140 | ++ '<span class="qs-option-name">' + |
| 141 | ++ ' <%- data.title %>' + |
| 142 | ++ '</span>' + |
| 143 | ++ '<span aria-hidden="true" class="amount">' + |
| 144 | ++ '<%- data.num_results %>' + |
| 145 | ++ '</span>' + |
| 146 | + '</li>', |
| 147 | + submitBtn: 'button[type="submit"]', |
| 148 | + searchLabel: '[data-role=minisearch-label]', |
| 149 | +@@ -297,60 +297,64 @@ define([ |
| 150 | + this.submitBtn.disabled = isEmpty(value); |
| 151 | + |
| 152 | + if (value.length >= parseInt(this.options.minSearchLength, 10)) { |
| 153 | +- $.getJSON(this.options.url, { |
| 154 | +- q: value |
| 155 | +- }, $.proxy(function (data) { |
| 156 | +- if (data.length) { |
| 157 | +- $.each(data, function (index, element) { |
| 158 | +- var html; |
| 159 | +- |
| 160 | +- element.index = index; |
| 161 | +- html = template({ |
| 162 | +- data: element |
| 163 | ++ this.submitBtn.disabled = false; |
| 164 | ++ |
| 165 | ++ if (this.options.url !== '') { //eslint-disable-line eqeqeq |
| 166 | ++ $.getJSON(this.options.url, { |
| 167 | ++ q: value |
| 168 | ++ }, $.proxy(function (data) { |
| 169 | ++ if (data.length) { |
| 170 | ++ $.each(data, function (index, element) { |
| 171 | ++ var html; |
| 172 | ++ |
| 173 | ++ element.index = index; |
| 174 | ++ html = template({ |
| 175 | ++ data: element |
| 176 | ++ }); |
| 177 | ++ dropdown.append(html); |
| 178 | + }); |
| 179 | +- dropdown.append(html); |
| 180 | +- }); |
| 181 | + |
| 182 | +- this._resetResponseList(true); |
| 183 | +- |
| 184 | +- this.responseList.indexList = this.autoComplete.html(dropdown) |
| 185 | +- .css(clonePosition) |
| 186 | +- .show() |
| 187 | +- .find(this.options.responseFieldElements + ':visible'); |
| 188 | +- |
| 189 | +- this.element.removeAttr('aria-activedescendant'); |
| 190 | +- |
| 191 | +- if (this.responseList.indexList.length) { |
| 192 | +- this._updateAriaHasPopup(true); |
| 193 | ++ this._resetResponseList(true); |
| 194 | ++ |
| 195 | ++ this.responseList.indexList = this.autoComplete.html(dropdown) |
| 196 | ++ .css(clonePosition) |
| 197 | ++ .show() |
| 198 | ++ .find(this.options.responseFieldElements + ':visible'); |
| 199 | ++ |
| 200 | ++ this.element.removeAttr('aria-activedescendant'); |
| 201 | ++ |
| 202 | ++ if (this.responseList.indexList.length) { |
| 203 | ++ this._updateAriaHasPopup(true); |
| 204 | ++ } else { |
| 205 | ++ this._updateAriaHasPopup(false); |
| 206 | ++ } |
| 207 | ++ |
| 208 | ++ this.responseList.indexList |
| 209 | ++ .on('click', function (e) { |
| 210 | ++ this.responseList.selected = $(e.currentTarget); |
| 211 | ++ this.searchForm.trigger('submit'); |
| 212 | ++ }.bind(this)) |
| 213 | ++ .on('mouseenter mouseleave', function (e) { |
| 214 | ++ this.responseList.indexList.removeClass(this.options.selectClass); |
| 215 | ++ $(e.target).addClass(this.options.selectClass); |
| 216 | ++ this.responseList.selected = $(e.target); |
| 217 | ++ this.element.attr('aria-activedescendant', $(e.target).attr('id')); |
| 218 | ++ }.bind(this)) |
| 219 | ++ .on('mouseout', function (e) { |
| 220 | ++ if (!this._getLastElement() && |
| 221 | ++ this._getLastElement().hasClass(this.options.selectClass)) { |
| 222 | ++ $(e.target).removeClass(this.options.selectClass); |
| 223 | ++ this._resetResponseList(false); |
| 224 | ++ } |
| 225 | ++ }.bind(this)); |
| 226 | + } else { |
| 227 | ++ this._resetResponseList(true); |
| 228 | ++ this.autoComplete.hide(); |
| 229 | + this._updateAriaHasPopup(false); |
| 230 | ++ this.element.removeAttr('aria-activedescendant'); |
| 231 | + } |
| 232 | +- |
| 233 | +- this.responseList.indexList |
| 234 | +- .on('click', function (e) { |
| 235 | +- this.responseList.selected = $(e.currentTarget); |
| 236 | +- this.searchForm.trigger('submit'); |
| 237 | +- }.bind(this)) |
| 238 | +- .on('mouseenter mouseleave', function (e) { |
| 239 | +- this.responseList.indexList.removeClass(this.options.selectClass); |
| 240 | +- $(e.target).addClass(this.options.selectClass); |
| 241 | +- this.responseList.selected = $(e.target); |
| 242 | +- this.element.attr('aria-activedescendant', $(e.target).attr('id')); |
| 243 | +- }.bind(this)) |
| 244 | +- .on('mouseout', function (e) { |
| 245 | +- if (!this._getLastElement() && |
| 246 | +- this._getLastElement().hasClass(this.options.selectClass)) { |
| 247 | +- $(e.target).removeClass(this.options.selectClass); |
| 248 | +- this._resetResponseList(false); |
| 249 | +- } |
| 250 | +- }.bind(this)); |
| 251 | +- } else { |
| 252 | +- this._resetResponseList(true); |
| 253 | +- this.autoComplete.hide(); |
| 254 | +- this._updateAriaHasPopup(false); |
| 255 | +- this.element.removeAttr('aria-activedescendant'); |
| 256 | +- } |
| 257 | +- }, this)); |
| 258 | ++ }, this)); |
| 259 | ++ } |
| 260 | + } else { |
| 261 | + this._resetResponseList(true); |
| 262 | + this.autoComplete.hide(); |
| 263 | + |
0 commit comments