@@ -16,6 +16,9 @@ define([
1616 */
1717 $ . widget ( 'mage.menu' , $ . ui . menu , {
1818 options : {
19+ productUrlSuffix : '' ,
20+ categoryUrlSuffix : '' ,
21+ useCategoryPathInUrl : false ,
1922 responsive : false ,
2023 expanded : false ,
2124 showDelay : 42 ,
@@ -122,7 +125,7 @@ define([
122125 var currentUrl = window . location . href . split ( '?' ) [ 0 ] ;
123126
124127 if ( ! this . _setActiveMenuForCategory ( currentUrl ) ) {
125- this . _setActiveMenuForProduct ( ) ;
128+ this . _setActiveMenuForProduct ( currentUrl ) ;
126129 }
127130 } ,
128131
@@ -135,9 +138,6 @@ define([
135138 * @private
136139 */
137140 _setActiveMenuForCategory : function ( url ) {
138- // Clear active state from all categories
139- this . _clearActiveState ( ) ;
140-
141141 var activeCategoryLink = this . element . find ( 'a[href="' + url + '"]' ) ,
142142 classes ,
143143 classNav ;
@@ -159,19 +159,6 @@ define([
159159 return true ;
160160 } ,
161161
162- /**
163- * Clears the active state from all menu items within the navigation element.
164- * It removes 'active' and 'has-active' classes from all list items (li elements),
165- * which are used to indicate the currently selected or parent of a selected item.
166- * This method is typically used to reset the menu's state before applying new active states.
167- *
168- * @return void
169- * @private
170- */
171- _clearActiveState : function ( ) {
172- this . element . find ( 'li' ) . removeClass ( 'active has-active' ) ;
173- } ,
174-
175162 /**
176163 * Sets 'has-active' CSS class to all parent categories which have part of provided class in childClassName
177164 *
@@ -198,46 +185,72 @@ define([
198185 } ,
199186
200187 /**
201- * Activates the category in the menu corresponding to the current product page.
202- * It resolves the category URL based on the referrer (if it's from the same domain),
203- * and then sets this category as active in the menu.
204- * If no suitable referrer URL is found, no category is set as active .
188+ * Sets the active category in the menu based on the current product page or referrer .
189+ * It checks if the current URL or the referrer URL ends with a category URL extension.
190+ * If a match is found, it sets the corresponding category as active in the menu.
191+ * If no suitable URL is found, it clears the active state from the menu .
205192 *
193+ * @param {String } currentUrl - current page URL without parameters
206194 * @return void
207195 * @private
208196 */
209- _setActiveMenuForProduct : function ( ) {
210- var categoryUrl = this . _resolveCategoryUrl ( ) ;
197+ _setActiveMenuForProduct : function ( currentUrl ) {
198+ var categoryUrlExtension = this . options . categoryUrlSuffix || '.html' ,
199+ possibleCategoryUrl ,
200+ firstCategoryUrl = this . element . find ( '> li a' ) . attr ( 'href' ) ;
201+
202+ if ( firstCategoryUrl ) {
203+ var referrer = document . referrer ;
204+
205+ // Check if the referrer is from the same domain
206+ if ( referrer && new URL ( referrer ) . hostname === window . location . hostname ) {
207+ // Remove any query parameters from the referrer URL
208+ var queryParamIndex = referrer . indexOf ( '?' ) ;
209+ if ( queryParamIndex > 0 ) {
210+ referrer = referrer . substring ( 0 , queryParamIndex ) ;
211+ }
212+ }
211213
212- if ( categoryUrl ) {
213- this . _setActiveMenuForCategory ( categoryUrl ) ;
214+ var isCategoryOrProductPage = this . _isCategoryOrProductPage ( currentUrl ) ;
215+
216+ if ( referrer && referrer . endsWith ( categoryUrlExtension ) && isCategoryOrProductPage ) {
217+ possibleCategoryUrl = referrer ;
218+ } else if ( isCategoryOrProductPage ) {
219+ possibleCategoryUrl = currentUrl . substring ( 0 , currentUrl . lastIndexOf ( '/' ) ) + categoryUrlExtension ;
220+ } else {
221+ this . _clearActiveState ( ) ;
222+ return ;
223+ }
224+
225+ this . _setActiveMenuForCategory ( possibleCategoryUrl ) ;
214226 }
215227 } ,
216228
217229 /**
218- * Resolves the category URL based on the referrer URL.
219- * Checks if the referrer URL belongs to the same domain and is a likely category page.
220- * If so, returns the referrer URL after stripping any query parameters.
221- * Returns null if no suitable referrer is found or if it cannot be determined to be a category page.
230+ * Determines whether the given URL is likely a category or product page.
231+ * It checks if the URL ends with the predefined product or category URL suffix.
222232 *
223- * @return {String|null } The URL of the category, or null if it cannot be determined.
233+ * @param {String } url - The URL to check.
234+ * @return {Boolean } - Returns true if the URL ends with a product or category URL suffix, false otherwise.
224235 * @private
225236 */
226- _resolveCategoryUrl : function ( ) {
227- var categoryUrl = document . referrer ;
228-
229- // Ensure the referrer is from the same domain
230- if ( categoryUrl && new URL ( categoryUrl ) . hostname === window . location . hostname ) {
231- // Remove any query parameters from the referrer URL
232- var queryParamIndex = categoryUrl . indexOf ( '?' ) ;
233- if ( queryParamIndex > 0 ) {
234- categoryUrl = categoryUrl . substring ( 0 , queryParamIndex ) ;
235- }
236- return categoryUrl ;
237- }
237+ _isCategoryOrProductPage : function ( url ) {
238+ var productSuffix = this . options . productUrlSuffix || '.html' ;
239+ var categorySuffix = this . options . categoryUrlSuffix || '.html' ;
238240
239- // Fallback or default behavior if no suitable referrer is found
240- return null ;
241+ return url . endsWith ( productSuffix ) || url . endsWith ( categorySuffix ) ;
242+ } ,
243+
244+ /**
245+ * Clears the active state from all menu items within the navigation element.
246+ * It removes 'active' and 'has-active' classes from all list items (li elements),
247+ * which are used to indicate the currently selected or parent of a selected item.
248+ *
249+ * @return void
250+ * @private
251+ */
252+ _clearActiveState : function ( ) {
253+ this . element . find ( 'li' ) . removeClass ( 'active has-active' ) ;
241254 } ,
242255
243256 /**
0 commit comments