1// TODO better list and translatable 2import { parseCondition, parseKeywords, removeDiacritics, extractRegExp } from '../search.js' 3import { parseSearchParams, mergeSearchParams } from '../url.js' 4 5const wordsToExcludeFromSearch = ['le', 'la', 'les', 'du', 'en', 'un', 'une'] 6 7export default { 8 data() { 9 return { 10 isLoading: false, 11 pendingRequest: null 12 } 13 }, 14 methods: 15 { 16 searchEntries(entries, search) { 17 switch (this.params.search) { 18 case 'dynamic': 19 return this.localSearch(entries, search) 20 case 'true': 21 return this.distantSearch(entries, search) 22 default: 23 return entries 24 } 25 }, 26 // Search through API 27 distantSearch(entries, search) { 28 if (this.isLoading) { 29 // Do not send multiple request in parrallel, wait for the first one to finish 30 this.pendingRequest = search 31 return 32 } 33 this.isLoading = true 34 this.pendingRequest = null 35 36 const vParams = mergeSearchParams(this.params, { keywords: search }, { returnMode: 'object', overrideKeywords: false, overrideQuery: false }) 37 38 $.getJSON(wiki.url('?api/entries/bazarlist'), vParams, (data) => { 39 this.isLoading = false 40 const searchedIds = data.entries.map((entry) => entry[0]) 41 this.searchedEntries = entries.filter((entry) => searchedIds.includes(entry.id_fiche)) 42 this.filterEntries() 43 if (this.pendingRequest) { 44 this.distantSearch(entries, this.pendingRequest) 45 } 46 }) 47 return this.searchedEntries 48 }, 49 // Search with existing data in javascript 50 localSearch(entries, search) { 51 const vThis = this 52 53 // Parse search as a keywords search string 54 55 const vParsedKeywords = parseKeywords(search) 56 57 vParsedKeywords.CNF = vParsedKeywords.CNF 58 .map((pAnd) =>
58 pAnd 59 .map((pOr) => removeDiacritics(pOr)) 60 .filter((pOr) => pOr.length > 2 && !wordsToExcludeFromSearch.includes(pOr))) 61 .filter((pAnd) => pAnd.length > 0) 62 63 vParsedKeywords.excludeds = vParsedKeywords.excludeds 64 .map((pExcluded) => removeDiacritics(pExcluded)) 65 .filter((pExcluded) => pExcluded.length > 2 && !wordsToExcludeFromSearch.includes(pExcluded)) 66 67 let vResult = entries.filter((pEntry) => { 68 pEntry.searchScore = 1 69 70 let vMatchedAnds = 0 71 let vAndsCount = 0 72 73 vParsedKeywords.CNF.every((pAnd) => { 74 let vMatchedOrs = 0 75 let vAndScore = 0 76 77 vAndsCount++ 78 79 pAnd.forEach((pOr) => { 80 let vMatchedFields = 0 81 let vOrScore = 0 82 83 vThis.params.searchfields.forEach((pField) => { 84 let vFieldValue = pEntry[pField] ? pEntry[pField] : '' 85 86 if (Array.isArray(vFieldValue)) vFieldValue = vFieldValue.join(' ') 87 88 vFieldValue = removeDiacritics(vFieldValue) 89 90 vFieldValue = vFieldValue.trim() 91 92 const vRegExp = extractRegExp(pOr) 93 94 if (vFieldValue) { 95 const vMatches = vFieldValue.match(new RegExp(vRegExp, 'gi')) 96 97 if (vMatches) { 98 vMatches.forEach((pMatch) => { 99 vOrScore += pField == 'bf_titre' ? 2 * (pMatch.length + 1) : pMatch.length + 1 100 vMatchedFields++ 101 }) 102 } 103 } 104 }) 105 106 vOrScore *= vMatchedFields + 1 107 108 vAndScore += vOrScore 109 110 if (vMatchedFields > 0) vMatchedOrs++ 111 }) 112 113 if (vAndScore == 0) { 114 pEntry.searchScore = 0 115 return false 116 } 117 118 vAndScore *= vMatchedOrs + 1 119 120 pEntry.searchScore += vAndScore 121 122 if (vMatchedOrs > 0) vMatchedAnds++ 123 124 return true 125 }) 126 127 if (vAndsCount > 0) { 128 pEntry.searchScore *= vMatchedAnds / vAndsCount 129 } 130 131 vParsedKeywords.excludeds.forEach((pExcluded) => { 132 vThis.params.searchfields.forEach((pField) => { 133 let vFieldValue = pEntry[pField] ? pEntry[pField] : '' 134 135 if (Array.isArray(vFieldValue)) vFieldValue = vFieldValue.join(' ') 136 137 vFieldValue = removeDiacritics(vFieldValue) 138 139 vFieldValue = vFieldValue.trim() 140 141 const vRegExp = extractRegExp(pExcluded) 142 143 if (vFieldValue) { 144 const vMatches = vFieldValue.match(new RegExp(pExcluded, 'g')) 145 146 if (vMatches) { 147 pEntry.searchScore = 0 148 } 149 } 150 }) 151 }) 152 153 return pEntry.searchScore > 0 154 }) 155 156 vResult = vResult.sort((a, b) => ((a.searchScore > b.searchScore) ? -1 : 1)) 157 return vResult 158 } 159 } 160}
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.