front_findstr-search_src_url.js

import { diff } from 'deep-object-diff';
import qs from 'qs';

const findstr = window.findstr || {};

document.addEventListener('findstrLoaded', function (e) {
	findstr.hooks.addAction(
		'searchResults',
		'urlManagement',
		(results, group, field, current_element, parameters) => {
			/**
			 * Disable the URL management
			 *
			 * When returning true, the URL management is disabled
			 *
			 * @hook urlManagementDisabled
			 *
			 * @param {boolean} disabled        - The disabled status
			 * @param {string}  group           - The group name
			 * @param {Object}  results         - The search results
			 * @param {Object}  field           - The field object
			 * @param {Object}  current_element - The current element who triggered the event
			 * @param {Object}  parameters      - The search parameters
			 *
			 * @return {boolean} The disabled status
			 */
			const disabled = findstr.hooks.applyFilters(
				'urlManagementDisabled',
				false,
				group,
				results,
				field,
				current_element,
				parameters
			);

			if (true === disabled) {
				return;
			}

			let diffFilters;
			let urlNeedUpdate = false;

			const groupQueryElement = document.querySelector(
				`[data-findstr-results="${group}"]`
			);

			if (groupQueryElement) {
				const groupDefaultQuery = JSON.parse(
					groupQueryElement.dataset.findstrQuery
				);

				const urlObject = {
					findstr: {},
				};

				const url = new URL(window.location.href);
				const isSearch =
					document.body.classList.contains('search') ||
					url.searchParams.has('s');
				if (isSearch) {
					urlObject.s = '';
				}

				if (0 < parameters.q.length) {
					urlObject.findstr.q = parameters.q;

					if (isSearch) {
						urlObject.s = parameters.q;
					}

					urlNeedUpdate = true;
				}

				diffFilters = diff(
					groupDefaultQuery.filter.clauses,
					parameters.filter.clauses
				);

				if (0 < Object.keys(diffFilters).length) {
					urlObject.findstr.filter = diffFilters;
					urlNeedUpdate = true;
				}

				if (1 < parameters.page) {
					urlObject.findstr.page = parameters.page;
					urlNeedUpdate = true;
				}

				if (
					qs.stringify(groupDefaultQuery.sort) !==
					qs.stringify(parameters.sort)
				) {
					urlObject.findstr.sort = parameters.sort;
					urlNeedUpdate = true;
				}

				if (0 < Object.keys(urlObject.findstr).length) {
					urlObject.findstr.group = group;
				}

				//urlNeedUpdate = false; //uncomment for debug
				if (true === urlNeedUpdate) {
					//urlObject.findstr.group = group;
					history.replaceState(
						urlObject,
						null,
						`?${qs.stringify(urlObject, {
							encodeValuesOnly: true,
							arrayFormat: 'brackets',
						})}`
					);
				} else {
					history.replaceState(null, null, '?');
				}

				//update global findstr object
				findstr.url = urlObject.findstr;

				/**
				 * Triggered when the URL is updated
				 *
				 * @hook urlUpdated
				 *
				 * @param {string} group           - The group name
				 * @param {Object} results         - The search results
				 * @param {Object} field           - The field object
				 * @param {Object} current_element - The current element who triggered the event
				 * @param {Object} parameters      - The search parameters
				 */
				findstr.hooks.doAction(
					'urlUpdated',
					group,
					results,
					field,
					current_element,
					parameters
				);
			}
		}
	);

	findstr.hooks.addFilter('searchResults', 'urlManagement', (results) => {
		results.hits.forEach((hit) => {
			if (
				'object' === typeof hit.language &&
				hit.permalinks !== undefined &&
				hit.permalinks[findstr.currentLanguage]
			) {
				hit.permalink = hit.permalinks[findstr.currentLanguage];
			}
		});
		return results;
	});
});