PageSourceSearch

https://reveillerlesliens.fr/tools/bazar/presentation/javascripts/url.js

js reveillerlesliens.fr collected 2026-09-28 15:11:48 UTC 6,433 bytes, 223 lines download raw bytes

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&param2=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(/&lt;/g, '<')
195            .replace(/&gt;/g, '>')
196            .replace(/&quot;/g, '"')
197            .replace(/&#039;/g, "'")
198            .replace(/&amp;/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.