PageSourceSearch

https://site.fr/_static/8c8af5c529149f32/scripts/features/news/news-shared.js

js site.fr collected 2026-09-24 18:20:14 UTC 8,968 bytes, 325 lines download raw bytes

1import { formatUrlTitle } from '../../client-utils.js';
2import {
3  slugifyLegacyUrl,
4  slugifyLegacyArticleUrl,
5  normalizePath,
6  createFormatter,
7  getEnvLocale,
8  getCanonicalContext,
9} from '../../client-utils.js';
10import { toText } from '../../value-utils.js';
11
12const NEWS_CANONICAL_PATH = '/news';
13const NEWS_CANONICAL_TEMPLATE = '/news/{slug}';
14
15const createCanonicalNewsPathsGetter = ({ localeResolver = getEnvLocale } = {}) => {
16  let cached = null;
17
18  return () => {
19    const envLocale = toText(localeResolver()).trim();
20    if (!envLocale) {
21      return null;
22    }
23    if (cached && cached.locale === envLocale) {
24      return cached;
25    }
26
27    const canonicalContext = getCanonicalContext(envLocale);
28    if (!canonicalContext?.context?.pathsData) {
29      return null;
30    }
31
32    const { i18nCore, context } = canonicalContext;
33    const urlLocale = context.urlLocaleRaw || envLocale;
34    const basePathRaw = i18nCore.resolvePath(context.pathsData, urlLocale, NEWS_CANONICAL_PATH, {});
35    const basePath = normalizePath(basePathRaw || NEWS_CANONICAL_PATH);
36    const buildPath = (slug) => i18nCore.resolvePath(context.pathsData, urlLocale, NEWS_CANONICAL_TEMPLATE, { slug });
37
38    cached = { locale: envLocale, basePath, buildPath };
39    return cached;
40  };
41};
42
43const resolveNewsHref = (slug, paths) => {
44  if (!paths) {
45    return '';
46  }
47  const normalizedSlug = toText(slug).trim();
48  if (!normalizedSlug) {
49    return paths.basePath;
50  }
51  const resolved = paths.buildPath(normalizedSlug);
52  return resolved || `${paths.basePath}/${normalizedSlug}`;
53};
54
55const getNewsForLocale = (serverData, locale) => {
56  const newsByLocale = serverData?.allNews;
57  if (!newsByLocale || typeof newsByLocale !== 'object') {
58    return null;
59  }
60  return Array.isArray(newsByLocale[locale]) ? newsByLocale[locale] : [];
61};
62
63const getNewsTagsForLocale = (serverData, locale) => {
64  const tagsByLocale = serverData?.newsTags;
65  if (!tagsByLocale || typeof tagsByLocale !== 'object') {
66    return null;
67  }
68  return Array.isArray(tagsByLocale[locale]) ? tagsByLocale[locale] : [];
69};
70
71const getNewsTagName = (tag) => {
72  if (!tag) {
73    return '';
74  }
75  if (typeof tag === 'string') {
76    return tag;
77  }
78  if (typeof tag === 'object') {
79    if (typeof tag.name === 'string') {
80      return tag.name;
81    }
82    if (typeof tag.tag?.name === 'string') {
83      return tag.tag.name;
84    }
85  }
86  return String(tag || '');
87};
88
89const getNewsItemTagId = (item, { fallbackToItemId = false } = {}) => {
90  if (!item || typeof item !== 'object') {
91    return null;
92  }
93  const explicit = item.tagId ?? item.tag_id ?? item.news_tag_id ?? null;
94  if (explicit !== null && explicit !== undefined) {
95    return explicit;
96  }
97  return fallbackToItemId ? (item.id ?? null) : null;
98};
99
100const buildNewsArticleSlug = (title, id) => {
101  if (id === undefined || id === null) {
102    return '';
103  }
104  const base = slugifyLegacyArticleUrl(title || '');
105  return `${base}-${id}`;
106};
107
108const resolveNewsArticleHref = (item, articleSlugsById, paths) => {
109  if (!paths) {
110    return '';
111  }
112  if (!item || item.id == null) {
113    return paths.basePath;
114  }
115  const slug = articleSlugsById?.get?.(String(item.id));
116  return resolveNewsHref(slug || String(item.id), paths);
117};
118
119const buildCanonicalArticleSlugs = (items, formatter) => {
120  const slugsById = new Map();
121  (Array.isArray(items) ? items : []).forEach((item) => {
122    if (!item || item.id == null) {
123      return;
124    }
125    const titleText = formatUrlTitle(item.title, formatter);
126    const id = String(item.id);
127    slugsById.set(id, buildNewsArticleSlug(titleText, item.id) || id);
128  });
129  return slugsById;
130};
131
132const buildCanonicalTagSlugMaps = ({
133  canonicalLocale,
134  canonicalFormatter,
135  newsByLocale,
136  tagsByLocale,
137  getTagName = getNewsTagName,
138  getItemTagId = getNewsItemTagId,
139} = {}) => {
140  const idToSlug = new Map();
141  const nameToSlug = new Map();
142  const articleIdToTagSlug = new Map();
143
144  const registerName = (name, slug) => {
145    const key = slugifyLegacyUrl(name);
146    if (!key) {
147      return;
148    }
149    nameToSlug.set(key, slug);
150  };
151
152  const registerCanonicalTag = (tag) => {
153    const name = formatUrlTitle(getTagName(tag), canonicalFormatter);
154    if (!name) {
155      return;
156    }
157    const slug = slugifyLegacyUrl(name);
158    if (!slug) {
159      return;
160    }
161    const id = tag.id;
162    if (id !== null && id !== undefined) {
163      idToSlug.set(String(id), slug);
164    }
165    registerName(name, slug);
166  };
167
168  const canonicalTags = tagsByLocale?.[canonicalLocale];
169  (Array.isArray(canonicalTags) ? canonicalTags : []).forEach(registerCanonicalTag);
170
171  const canonicalNews = newsByLocale?.[canonicalLocale];
172  (Array.isArray(canonicalNews) ? canonicalNews : []).forEach((item) => {
173    if (!item || item.id == null) {
174      return;
175    }
176    const name = formatUrlTitle(getTagName(item?.tag ?? ''), canonicalFormatter);
177    if (!name) {
178      return;
179    }
180    const slug = slugifyLegacyUrl(name);
181    if (!slug) {
182      return;
183    }
184    articleIdToTagSlug.set(String(item.id), slug);
185    const id = getItemTagId(item);
186    if (id !== null && id !== undefined && !idToSlug.has(String(id))) {
187      idToSlug.set(String(id), slug);
188    }
189    registerName(name, slug);
190  });
191
192  if (newsByLocale && typeof newsByLocale === 'object') {
193    Object.entries(newsByLocale).forEach(([locale, news]) => {
194      const localeFormatter = createFormatter(locale);
195      (Array.isArray(news) ? news : []).forEach((item) => {
196        if (!item || item.id == null) {
197          return;
198        }
199        const slug = articleIdToTagSlug.get(String(item.id));
200        if (!slug) {
201          return;
202        }
203        const tagName = String(localeFormatter.toText(getTagName(item?.tag ?? '') ?? '')).trim();
204        if (tagName) {
205          registerName(tagName, slug);
206        }
207        const tagId = getItemTagId(item);
208        if (tagId !== null && tagId !== undefined && !idToSlug.has(String(tagId))) {
209          idToSlug.set(String(tagId), slug);
210        }
211      });
212    });
213  }
214
215  if (tagsByLocale && typeof tagsByLocale === 'object') {
216    Object.entries(tagsByLocale).forEach(([locale, tags]) => {
217      const localeFormatter = createFormatter(locale);
218      (Array.isArray(tags) ? tags : []).forEach((tag) => {
219        const name = String(localeFormatter.toText(getTagName(tag) ?? '')).trim();
220        if (!name) {
221          return;
222        }
223
224        const id = tag.id;
225        let slug = '';
226        if (id !== null && id !== undefined) {
227          slug = idToSlug.get(String(id)) || '';
228        }
229        if (!slug) {
230          slug = nameToSlug.get(slugifyLegacyUrl(name)) || '';
231        }
232        if (!slug) {
233          return;
234        }
235        if (id !== null && id !== undefined && !idToSlug.has(String(id))) {
236          idToSlug.set(String(id), slug);
237        }
238        registerName(name, slug);
239      });
240    });
241  }
242
243  return { idToSlug, nameToSlug };
244};
245
246const resolveTagSlug = (tagText, tagId, slugMaps) => {
247  if (tagId !== null && tagId !== undefined) {
248    const mapped = slugMaps.idToSlug.get(String(tagId));
249    if (mapped) {
250      return mapped;
251    }
252  }
253  const nameKey = slugifyLegacyUrl(tagText);
254  if (nameKey) {
255    const mapped = slugMaps.nameToSlug.get(nameKey);
256    if (mapped) {
257      return mapped;
258    }
259  }
260  return '';
261};
262
263const resolveTagSlugFromPath = (pathname, basePath) => {
264  const normalizedBase = normalizePath(basePath);
265  if (!normalizedBase) {
266    return '';
267  }
268
269  const normalizedPath = normalizePath(pathname || '');
270  if (!normalizedPath || normalizedPath === normalizedBase) {
271    return '';
272  }
273  if (!normalizedPath.startsWith(`${normalizedBase}/`)) {
274    return '';
275  }
276
277  const suffix = normalizedPath.slice(normalizedBase.length + 1).replace(/\/+$/g, '');
278  if (!suffix || suffix.includes('/')) {
279    return '';
280  }
281
282  try {
283    return slugifyLegacyUrl(decodeURIComponent(suffix));
284  } catch {
285    return slugifyLegacyUrl(suffix);
286  }
287};
288
289const resolveNewsArticleId = ({ attrValue, pathname = '', basePath = '' } = {}) => {
290  const numeric = Number(attrValue);
291  if (Number.isFinite(numeric)) {
292    return numeric;
293  }
294
295  const normalizedBase = normalizePath(basePath);
296  const normalizedPath = normalizePath(pathname || '');
297  if (!normalizedBase || !normalizedPath || !normalizedPath.startsWith(`${normalizedBase}/`)) {
298    return null;
299  }
300
301  const suffix = normalizedPath.slice(normalizedBase.length + 1).replace(/\/+$/g, '');
302  if (!suffix || suffix.includes('/')) {
303    return null;
304  }
305
306  const normalizedSlug = slugifyLegacyArticleUrl(suffix);
307  const last = normalizedSlug.split('-').pop();
308  const id = Number(last);
309  return Number.isFinite(id) ? id : null;
310};
311
312export {
313  createCanonicalNewsPathsGetter,
314  resolveNewsHref,
315  getNewsForLocale,
316  getNewsTagsForLocale,
317  getNewsTagName,
318  getNewsItemTagId,
319  resolveNewsArticleHref,
320  buildCanonicalArticleSlugs,
321  buildCanonicalTagSlugMaps,
322  resolveTagSlug,
323  resolveTagSlugFromPath,
324  resolveNewsArticleId,
325};

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.