UNPKG

@atlaskit/editor-common

Version:

A package that contains common classes and components for editor and renderer

161 lines (150 loc) 6.27 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; import { areUserPreferencesEqual, mergeUserPreferences } from './utils'; /** * This class is used to manage user preferences in the editor. * It provides methods to load, update, and get user preferences, * as well as a way to subscribe to updates. * @example const userPreferencesProvider = new UserPreferencesProvider(persistenceAPI, defaultPreferences); */ export class UserPreferencesProvider { /** * This is the constructor for the UserPreferencesProvider class. * @param persistenceAPI - The persistence API to use for loading and updating user preferences * @param defaultPreferences - The default user preferences to use * @param initialUserPreferences - The initial user preferences to use (optional) * @example const userPreferencesProvider = new UserPreferencesProvider(persistenceAPI, defaultPreferences); */ constructor(persistenceAPI, defaultPreferences) { var _this$persistenceAPI$, _this$persistenceAPI; _defineProperty(this, "updateCallbacks", []); _defineProperty(this, "userPreferences", {}); _defineProperty(this, "initialized", false); this.persistenceAPI = persistenceAPI; this.defaultPreferences = defaultPreferences; this.resolvedUserPreferences = defaultPreferences; const initialUserPreferences = (_this$persistenceAPI$ = (_this$persistenceAPI = this.persistenceAPI).getInitialUserPreferences) === null || _this$persistenceAPI$ === void 0 ? void 0 : _this$persistenceAPI$.call(_this$persistenceAPI); if (initialUserPreferences) { this.setUserPreferences(initialUserPreferences); } // the initial user preferences might come from the local cache, // so we need to always load the preferences this.loadPreferences(); } /** * This method returns the initialized state of the user preferences provider * @returns true if the user preferences provider is initialized, false otherwise * @example userPreferencesProvider.isInitialized */ get isInitialized() { return this.initialized; } /** * This method fetches the latest user preferences * @returns a promise that resolves with the user preferences, or rejects if error occurs * @throws Error if there is an error loading user preferences * @example userPreferencesProvider.loadPreferences() */ async loadPreferences() { const userPreferences = await this.persistenceAPI.loadUserPreferences(); this.setUserPreferences(userPreferences); } /** * This method updates a user preference * @param key * @param value * @returns a promise that resolves when the user preference is updated * @throws Error if there is an error updating user preferences * @example userPreferencesProvider.updatePreference('toolbarDockingPosition', 'top') */ async updatePreference(key, value) { const userPreferences = await this.persistenceAPI.updateUserPreference(key, value); this.setUserPreferences(userPreferences); } /** * get a user preference, Note that this function is a not async function, * meaning that consumers should prefetch the user preference and make it available initially * @param key * @returns the user preference * @example userPreferencesProvider.getPreference('toolbarDockingPosition') */ getPreference(key) { return this.resolvedUserPreferences[key]; } /** * get all user preferences * @returns the user preferences * @example userPreferencesProvider.getPreferences() */ getPreferences() { return this.resolvedUserPreferences; } /** * This method fetches the latest user preferences * @param onUpdate * @returns a function to unsubscribe from the updates * @example */ onUpdate(onUpdate) { this.updateCallbacks.push(onUpdate); // Return the cleanup function to unsubscribe from the updates return () => { this.updateCallbacks = this.updateCallbacks.filter(callback => callback !== onUpdate); }; } /** * This method is used to set the default user preferences, * setting the default user preferences will also trigger an update * This is useful when the default user preferences dynamically based on the context * @param preferences * @example */ setDefaultPreferences(preferences) { this.defaultPreferences = preferences; const hasUpdated = this.resolveUserPreferences(); if (hasUpdated) { this.notifyUserPreferencesUpdated(); } } setUserPreferences(userPreferences) { this.userPreferences = userPreferences; const hasUpdated = this.resolveUserPreferences(); if (hasUpdated || !this.initialized) { if (!this.initialized) { this.initialized = true; } this.notifyUserPreferencesUpdated(); } } /** * This method is used to notify the user preferences updated * @example userPreferencesProvider.notifyUserPreferencesUpdated() */ notifyUserPreferencesUpdated() { this.updateCallbacks.forEach(callback => { callback(this.resolvedUserPreferences); }); } /** * This method resolves the user preferences by merging the default preferences * with the user preferences and filtering out any undefined or null values * to avoid overwriting default preferences with null values * @returns true if the user preferences were updated, false otherwise * @example userPreferencesProvider.resolveUserPreferences() */ resolveUserPreferences() { // Merge default preferences with user preferences // and filter out any undefined or null values // to avoid overwriting default preferences with null values const newResolvedUserPreferences = mergeUserPreferences(this.userPreferences, this.defaultPreferences); // if the user preferences is NOT initialized, we need to update and notify // the user preferences // if the user preferences is initialized, we need to check if the new user preferences // is different from the old user preferences const isSame = areUserPreferencesEqual(newResolvedUserPreferences, this.resolvedUserPreferences); const needUpdate = !isSame; if (needUpdate) { this.resolvedUserPreferences = newResolvedUserPreferences; } return needUpdate; } }