UNPKG

coveo-search-ui

Version:

Coveo JavaScript Search Framework

88 lines (75 loc) 3.41 kB
import { localStorageExists, LocalStorageUtils } from '../utils/LocalStorageUtils'; import { Model } from '../models/Model'; import { QueryController } from './QueryController'; import { Logger } from '../misc/Logger'; import { Assert } from '../misc/Assert'; import { InitializationEvents } from '../events/InitializationEvents'; import { RootComponent } from '../ui/Base/RootComponent'; import { $$ } from '../utils/Dom'; import { each, omit } from 'underscore'; import { IHistoryManager } from './HistoryManager'; /** * This component acts like the {@link HistoryController} excepts that is saves the {@link QueryStateModel} in the local storage.<br/> * This will not allow 'back' and 'forward' navigation in the history, like the standard {@link HistoryController} allows. Instead, it load the query state only on page load.<br/> * To enable this component, you should set the {@link SearchInterface.options.useLocalStorageForHistory} as well as the {@link SearchInterface.options.enableHistory} options to true. */ export class LocalStorageHistoryController extends RootComponent implements IHistoryManager { static ID = 'LocalStorageHistoryController'; public storage: LocalStorageUtils<{ [key: string]: any }>; private omit: string[] = []; /** * Create a new LocalStorageHistoryController instance * @param element * @param windoh For mock purpose * @param model * @param queryController */ constructor(element: HTMLElement, public windoh: Window, public model: Model, public queryController: QueryController) { super(element, LocalStorageHistoryController.ID); if (!localStorageExists) { new Logger(element).info( 'No local storage available in current browser. LocalStorageHistoryController cannot initialize itself', this ); } else { this.storage = new LocalStorageUtils<{ [key: string]: any }>(LocalStorageHistoryController.ID); Assert.exists(this.model); Assert.exists(this.queryController); $$(this.element).on(InitializationEvents.restoreHistoryState, () => this.initModelFromLocalStorage()); $$(this.element).on(this.model.getEventName(Model.eventTypes.all), () => this.updateLocalStorageFromModel()); } } public replaceState(state: Record<string, any>) { this.storage.save(state); } /** * Specifies an array of attributes from the query state model that should not be persisted in the local storage * @param attributes */ public withoutThoseAttribute(attributes: string[]) { this.omit = attributes; } public setState(values: Record<string, any>) { this.storage.save(values); } private updateLocalStorageFromModel() { const attributes = omit(this.model.getAttributes(), this.omit); this.setState(attributes); this.logger.debug('Saving state to localstorage', attributes); } private initModelFromLocalStorage() { const model = this.localStorageModel; this.model.setMultiple(model); } private get localStorageModel() { const model: Record<string, any> = {}; const storedValues = this.storage.load() || {}; each(this.model.attributes, (value, key) => { const storedValue = storedValues[key]; const defaultValue = this.model.defaultAttributes[key]; const valueToSet = storedValue == undefined ? defaultValue : storedValue; model[key] = valueToSet; }); return model; } }