1import { updateExportLinks } from './export.js' 2import { parseCondition } from './search.js' 3 4/** 5 * Parse URL parameters string and return a structured object reprensenting it 6 * @param <string> pParams 7 * @return <object> in the form : 8 * { 9 * keywords : <string> the keywords string like : 'toto "tata tata" | titi -tutu' 10 * champ : <string> the sort field 11 * ordre : <string> the direction of the sort "asc" or "desc" 12 * query : <array> of condition object { name : <string>, operator : string, values : [ <string>, ... ]} 13 * any other parameter... : <string> 14 * } 15 */ 16 17export function parseSearchParams(pParams) { 18 // Return params as a structured object 19 const vParams = new URLSearchParams(pParams) 20 21 const vParseds = {} 22 23 for (const cKey of vParams.keys()) { 24 const vValue = vParams.get(cKey) 25 26 if ( 27 cKey == 'q' || 28 cKey == 'keywords' 29 ) // keywords supports for clarity (q parameter is confusing with query parameter) 30 { 31 if (vValue && vValue.trim() !== '') 32 vParseds.keywords = decodeURIComponent(vValue) // privilegiate use of "keywords" 33 } else if (cKey == 'champ' || cKey == 'ordre') { 34 vParseds[cKey] = vValue 35 } else if (cKey == 'query') { 36 if (vValue && vValue.trim() !== '') 37 vParseds[cKey] = decodeURIComponent(vValue) 38 .split('|') 39 .map(parseCondition) 40 } else { 41 vParseds[cKey] = vValue 42 } 43 } 44 45 return vParseds 46} 47 48/** 49 * Merge 2 search parameters. 50 * @param pParam1, pParam1 : 51 * <string> = URL parameters (ex :"param1=toto¶m2=tata") 52 * or 53 * <object> = structured object of parameters like the ones returned by parseSearchParams 54 * @pOptions : <object> containing optional keys 55 * - returnMode : <string> set the return type of this method = "string" returns concatenated URL parameters as string, or "object" returns concatenated URL parameters as object 56 * - overrideKeywords : <boolean> false = concatenate keywords with |, true = override value with pParam2's keywords 57 * - overrideQuery : <boolean> 58 * false = replace query's field parameter with same name and operator == by those of pParam2's or concatenate the 2 queries with | if it doesn't exist, 59 * true = merge values with pParam2's keywords overriding the complete query of pParam1 60 * @return the concatenated URL parameters as <string> or <object> 61 */ 62 63export function mergeSearchParams( 64 pParams1, 65 pParams2, 66 pOptions = { 67 returnMode: 'string', 68 overrideKeywords: false, 69 overrideQuery: false, 70 }, 71) { 72 const vMerged = {} 73 let vQuery 74 let vKeywords 75 76 const vParamsObject1 = 77 typeof pParams1 == 'string' ? parseSearchParams(pParams1) : pParams1 78 const vParamsObject2 = 79 typeof pParams2 == 'string' ? parseSearchParams(pParams2) : pParams2 80 81 $.extend(true, vMerged, vParamsObject1, vParamsObject2) 82 83 // Merge query parameter 84 85 if ( 86 vParamsObject1.query && 87 vParamsObject1.query.length > 0 && 88 vParamsObject2.query && 89 vParamsObject2.query.length > 0 90 ) { 91 if (pOptions.overrideQuery) { 92 vQuery = vParamsObject2.query 93 } else { 94 vParamsObject2.query.forEach((pCondition2) => { 95 let vFound = false 96 97 vParamsObject1.query.map((pCondition1) => { 98 if ( 99 pCondition1.name === pCondition2.name && 100 pCondition1.operator === pCondition2.operator 101 ) { 102 vFound = true 103 return pCondition2 104 } 105 return pCondition1 106 }) 107 108 if (!vFound) vParamsObject1.query.push(pCondition2) 109 }) 110 111 vQuery = vParamsObject1.query 112 } 113 } else if (vParamsObject1.query && vParamsObject1.query.length > 0) { 114 vQuery = vParamsObject1.query 115 } else if (vParamsObject2.query && vParamsObject2.query.length > 0) { 116 vQuery = vParamsObject2.query 117 } 118 119 if (vQuery !== undefined) { 120 // Remove duplicates and rebuild the query string 121 if (typeof vQuery === 'string') { 122 vQuery = [...new Set(vQuery.split('|'))].join('|') 123 } else { 124 vQuery = [ 125 ...new Set( 126 vQuery.map(({ name, operator, values }) => name + operator + values), 127 ), 128 ].join('|') 129 } 130 131 if (vQuery.trim() != '') vMerged.query = vQuery 132 } 133 134 // Merge keywords parameter 135 136 if (vParamsObject1.keywords && vParamsObject2.keywords) { 137 vKeywords = `${vParamsObject1.keywords}|${vParamsObject2.keywords}` 138 } else if (vParamsObject1.keywords) { 139 vKeywords = vParamsObject1.keywords 140 } else if (vParamsObject2.keywords) { 141 vKeywords = vParamsObject2.keywords 142 } 143 144 if (vKeywords != null && vKeywords.trim() != '') { 145 // URI encode the keywords 146 147 // Remove duplicates and rebuild the query string 148 149 vKeywords = [...new Set(vKeywords.split('|'))].join('|') 150
151 if (vKeywords.trim() != '') vMerged.keywords = vKeywords 152 } 153 154 if (pOptions.returnMode == 'string') return $.param(vMerged) 155 return vMerged 156} 157 158/* 159 * updateHash with given parameters 160 */ 161 162export function updateHash( 163 pSavedHash = '', 164 pKeywords = '', 165 pSortField = '', 166 pSortOrder = '', 167 pFilters = [], 168) { 169 const cCurrentHash = pSavedHash 170 171 const vQuery = [] 172 const vCurrentParams = {} 173 let vMergedParams 174 175 let vSearch = pKeywords != null ? pKeywords.trim() : '' 176 177 if (vSearch.length < wiki.minSearchKeywordLength) vSearch = '' 178 179 if (vSearch != '') vCurrentParams.keywords = vSearch 180 if (pSortField && pSortField != '') vCurrentParams.champ = pSortField 181 if (pSortOrder && pSortOrder != '') vCurrentParams.ordre = pSortOrder 182 183 let bHasFilter = false 184 185 for (const cFilterId in pFilters) { 186 bHasFilter = true 187 188 vQuery.push({ 189 name: cFilterId, 190 operator: '==', 191 values: pFilters[cFilterId] 192 .map((pString) => 193 pString 194 .replace(/</g, '<') 195 .replace(/>/g, '>') 196 .replace(/"/g, '"') 197 .replace(/'/g, "'") 198 .replace(/&/g, '&'), 199 ) 200 .join(','), 201 }) 202 } 203 204 if (bHasFilter) vCurrentParams.query = vQuery 205 206 vMergedParams = mergeSearchParams(cCurrentHash, vCurrentParams, { 207 returnMode: 'string', 208 overrideKeywords: true, 209 overrideQuery: true, 210 }) 211 212 // Encode the hash to avoid confusion between &-separated hash parameters and &-separated search parameters 213 214 history.pushState( 215 {}, 216 '', 217 vMergedParams 218 ? `#${encodeURIComponent(vMergedParams)}` 219 : location.pathname + location.search, 220 ) 221 222 updateExportLinks(vMergedParams) // Export 223}
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.