1import { DEFAULT_PAGE_SIZE, LAZY_LOAD_ITEMS_SIZE, MAX_PAGE_SIZE } from '../plp-constants.js'; 2 3const { SortBy } = window.CoveoHeadless; 4 5export default function composableVHelper() { 6 const compareSortCriteria = (criteria1, criteria2) => { 7 if (!criteria1 || !criteria2) { 8 return false; 9 } 10 11 if (criteria1.by === SortBy.Relevance && criteria2.by === SortBy.Relevance) { 12 return true; 13 } 14 15 if (criteria1.by === SortBy.Fields && criteria2.by === SortBy.Fields) { 16 if (!criteria1.fields || !criteria2.fields) { 17 return false; 18 } 19 if (criteria1.fields.length !== criteria2.fields.length) { 20 return false; 21 } 22 23 return criteria1.fields.every((field1, index) => { 24 const field2 = criteria2.fields[index]; 25 return field1.name === field2.name && field1.direction === field2.direction; 26 }); 27 } 28 29 return false; 30 }; 31 32 // This is injected during the initial DOM creation and acts as the PLP color picker flag. 33 // We use it here because value-init runs after getFragment is called (onMount). 34 const getIsPlpColorPickerEnabled = () => { 35 return ACC?.config?.isPlpColorPickerEnabled; 36 }; 37 38 function getCoveoDeserialize() { 39 // Returns Coveo's deserialize helper, which keeps recognized Coveo params 40 // and ignores params that are not managed by Coveo. 41 const coveoHeadless = typeof window !== 'undefined' ? window.CoveoHeadless : undefined; 42 43 return coveoHeadless?.productListingSerializer?.deserialize || coveoHeadless?.searchSerializer?.deserialize; 44 } 45 46 function isCoveoKey(key, params, deserialize) { 47 const singleParam = new URLSearchParams(); 48 49 for (const value of params.getAll(key)) { 50 singleParam.append(key, value); 51 } 52 53 const deserialized = deserialize(singleParam.toString()); 54 55 return Object.keys(deserialized).length > 0; 56 } 57 58 function getNonCoveoKeys(fragment) { 59 const deserialize = getCoveoDeserialize(); 60 61 if (!deserialize) { 62 return []; 63 } 64 65 const params = new URLSearchParams(fragment); 66 const keys = [...new Set(params.keys())]; 67 68 return keys.filter((key) => !isCoveoKey(key, params, deserialize)); 69 } 70 71 // Keep commas unencoded in values. 72 // Coveo expects ec_brand=one,two (literal commas) for multi-select; 73 // default encoders turn "," into "%2C" and break splitting. 74 // We encode everything else. 75 const encodeCoveoParam = (s) => encodeURIComponent(s).replace(/%2C/gi, ','); 76 77 const serializeCoveoParams = (params) => { 78 return Array.from(params.entries()) 79 .map(([key, value]) => `${encodeCoveoParam(key)}=${encodeCoveoParam(value)}`) 80 .join('&'); 81 }; 82 83 // Merges the latest Coveo fragment with external URL params. 84 // Coveo-owned params from the previous fragment are not re-added if Coveo removed them. 85 function mergeExternalParams(nextCoveoFragment, currentSearch, externalKeys) { 86 const nextParams = new URLSearchParams(nextCoveoFragment); 87 const currentParams = new URLSearchParams(currentSearch); 88 89 for (const key of externalKeys) { 90 if (!currentParams.has(key)) continue; 91 if (nextParams.has(key)) continue; 92 for (const value of currentParams.getAll(key)) { 93 nextParams.append(key, value); 94 } 95 } 96 97 return serializeCoveoParams(nextParams); 98 } 99 100 const getFragment = () => { 101 const queryParams = new URLSearchParams(window.location.search); 102 103 // Redirect color filter params based on the active PLP color picker experience. 104 // If the color picker is enabled, use shade; otherwise, use group. 105 // This keeps saved or shared URLs working by mapping old filter params to the expected one. 106 const isPlpColorPickerEnabled = getIsPlpColorPickerEnabled(); 107 const colorShadeKey = 'f-ec_color_shade'; 108 const colorGroupKey = 'f-ec_color_group'; 109 110 if (!isPlpColorPickerEnabled && queryParams.has(colorShadeKey)) { 111 queryParams.set(colorGroupKey, queryParams.get(colorShadeKey) || ''); 112 queryParams.delete(colorShadeKey); 113 } else if (isPlpColorPickerEnabled && queryParams.has(colorGroupKey)) { 114 queryParams.set(colorShadeKey, queryParams.get(colorGroupKey) || ''); 115 queryParams.delete(colorGroupKey); 116 } 117 118 // For the Coveo library to load the search parameter correctly, 119 // it should be in "q" instead of "text" as in our current implementation. 120 if (queryParams.has('text') && !queryParams.has('q')) { 121 queryParams.set('q', queryParams.get('text') || ''); 122 queryParams.delete('text'); 123 } 124 125 if (!queryParams.has('perPage')) { 126 queryParams.set('perPage', String(DEFAULT_PAGE_SIZE)); 127 } 128 129 if (Number(queryParams.get('perPage')) === MAX_PAGE_SIZE) { 130 queryParams.delete('page'); 131 queryParams.set('perPage', String(LAZY_LOAD_ITEMS_SIZE)); 132 } 133 134 return serializeCoveoParams(queryParams); 135 }; 136 137 return { 138 compareSortCriteria, 139 getFragment, 140 serializeCoveoParams, 141 mergeExternalParams, 142 getNonCoveoKeys 143 }; 144}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.