PageSourceSearch

https://culturepointwapi.be/tools/bazar/presentation/javascripts/search.js

js culturepointwapi.be collected 2026-09-26 12:29:18 UTC 5,920 bytes, 198 lines download raw bytes

1/**
2 * Parse a condition like bf_myfield == value1, value2
3 *
4 * @param pValue <string> : the condition string to parse
5 *
6 * @return <object> : an object in the form { name : <string>, operator : <string>, values : [ string, ... ] }
7 */
8
9export function parseCondition(pValue) {
10  // Extraire nom, opérateur et valeurs
11  const regex = /\s*([^=!<>]*)\s*(==|!=|<=|>=|=|<|>)(.*)/
12  const matches = pValue.match(regex)
13
14  if (!matches) return null
15
16  const vName = matches[1].trim()
17  let vOperator = matches[2].trim()
18  const rawValues = matches[3].trim()
19
20  // Convertir l'opérateur "=" en "=="
21  if (vOperator === '=') vOperator = '=='
22
23  // Transformer la liste en tableau avec valeurs uniques
24  const vUniqueValues = Array.from(
25    new Set(
26      rawValues
27        .split(',')
28        .map((v) => v.trim())
29        .filter((v) => v !== ''),
30    ),
31  )
32
33  // Retourner la structure
34
35  const vResult = {
36    name: vName,
37    operator: vOperator,
38    values: vUniqueValues,
39  }
40
41  return vResult
42}
43
44/**
45 * Parse a keywords search string
46 * Keywords search string are composed of tokens
47 * Tokens can be single words (without space) or expression composed of several words seperated by spaces enclosed in quote or double quote.
48 * Tokens may be separated by |
49 * | stands for logical AND
50 * A token may be prefixed with - to exclude the results containing the token
51 * The position of excluded tokens is not relevant
52 * Ex : cat "my dog" -parrot | bulldog "small bird" -"cocker spaniel"
53 *    will match result that contain ("cat" or "my dog") and ("bulldog" or "small bird)
54 *    excluding results containing "parrot" or "cocker spaniel"
55 *
56 * @param pKeywords <string> : the keywords search string
57 *
58 * @return <array> : the parsed string as an associative array containing the keys :
59 * 	- CNF =	the Conjonctive Normal Form (= [a OR b] AND [d or e]) of the keywords search string
60 *			(ie : an AND-array of OR-arrays)
61 *	- excludeds = <array> an array of excluded tokens
62 */
63
64export function parseKeywords(pKeywords) {
65  const _t = (_key) => 'BAZ_MOT_CLE' // Remplace ça par ton système de traduction si besoin
66
67  // Résultat par défaut
68  const results = { CNF: [], excludeds: [] }
69
70  // Vérification de validité
71  if (
72    typeof pKeywords !== 'string' ||
73    pKeywords.trim() === '' ||
74    pKeywords === _t('BAZ_MOT_CLE')
75  ) {
76    return results
77  }
78
79  // Séparation des clauses AND par "|"
80  const andClauses = pKeywords.split('|').map((clause) => clause.trim())
81
82  for (const andClause of andClauses) {
83    // Extraction des tokens via RegEx
84    const regex = /(-)?("(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\S+)/gu
85    let match
86    const ors = []
87
88    while ((match = regex.exec(andClause)) !== null) {
89      const isExcluded = match[1] === '-'
90      const rawToken = match[2]
91      const cleanedToken = rawToken.replace(/^["']|["']$/g, '') // Supprime les guillemets
92
93      if (isExcluded) {
94        results.excludeds.push(cleanedToken)
95      } else {
96        ors.push(cleanedToken)
97      }
98    }
99
100    results.CNF.push(ors)
101  }
102
103  return results
104}
105
106/**
107 * Test if a string represents a regexp
108 * A string is considered as a regexp if it contains at least one ".*"
109 * or if it begins and ends with "/"
110 * @pString <string> : the string to test
111 * @return <boolean> : true if the string represent a regexp, false otherwise
112 */
113
114export function isRegExp(str) {
115  return (
116    typeof str === 'string' &&
117    (str.includes('.*') || (str.startsWith('/') && str.endsWith('/')))
118  )
119}
120
121export function removeDiacritics(str) {
122  return str
123    .normalize('NFD')
124    .replace(/[\u0300-\u036f]/g, '')
125    .toLowerCase()
126}
127
128/**
129 * Normalise une chaîne :
130 *   - met en minuscules (Unicode-safe)
131 *   - transforme les caractères accentués en leur équivalent non accentué
132 *   - gère les ligatures courantes (œ, æ, ß, etc.)
133 *
134 * @param <string>
134 : chaîne d'entrée (n'importe quel encodage détectable)
135 * @return <string> : chaîne lowercase, sans accents
136 */
137
138export function toLowerCaseWithoutAccent(str) {
139  if (typeof str !== 'string') return ''
140
141  // 1. Lowercase unicode
142  str = str.toLowerCase()
143
144  // 2. Remplacer les ligatures
145  const replacements = {
146    œ: 'oe',
147    æ: 'ae',
148    ß: 'ss',
149    ø: 'o',
150    ð: 'd',
151    þ: 'th',
152  }
153
154  str = str.replace(/œ|æ|ß|ø|ð|þ/g, (match) => replacements[match])
155
156  // 3. Décomposition unicode (NFD) + suppression des diacritiques
157  str = str.normalize('NFD').replace(/[\u0300-\u036f]/g, '')
158
159  // 4. Translitération ASCII (approximative via normalisation)
160  // Pas d'équivalent direct à `iconv`, mais `normalize` fait une bonne partie du travail
161
162  return str
163}
164
165/**
166 * Extract and transform a regexp string from a string recognized by isRegExp as a regexp
167 * + It removes beginning and ending "/" if it exists
168 * + Optionnaly, it add alternatives for each character that has an accented version
169 * @param pString : <string> a regexp string recognized by isRegExp as a regexp
170 * @param pAccentInsensitive : <boolean> true to make the regexp accent insensitive
171 *
172 * @return <string> : the transformed regexp string
173 */
174
175export function extractRegExp(pString, accentInsensitive = true) {
176  let vString
177
178  if (pString.startsWith('/') && pString.endsWith('/')) {
179    vString = pString.slice(1, -1)
180  } else {
181    vString = pString
182  }
183
184  if (accentInsensitive) {
185    vString = toLowerCaseWithoutAccent(vString)
186
187    vString = vString.replace(/a/g, '(a|à|á|â|ã|ä|A|À|Á|Â|Ã|Ä)')
188    vString = vString.replace(/c/g, '(c|ç|C|Ç)')
189    vString = vString.replace(/e/g, '(e|è|é|ê|ë|E|È|É|Ê|Ë)')
190    vString = vString.replace(/i/g, '(i|ì|í|î|ï|I|Ì|Í|Î|Ï)')
191    vString = vString.replace(/n/g, '(n|ñ|N|Ñ)')
192    vString = vString.replace(/o/g, '(o|ò|ó|ô|õ|ö|O|Ò|Ó|Ô|Õ|Ö)')
193    vString = vString.replace(/u/g, '(u|ù|ú|û|ü|U|Ù|Ú|Û|Ü)')
194    vString = vString.replace(/y/g, '(y|ý|ÿ|Y|Ý)')
195  }
196
197  return vString
198}

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.