WordPress/wp-includes/js/dist/preferences.js
hellofromTonya 8c85dde1c6 Editor: Persist preferences in user meta.
Adds a new feature to persist editor UI preferences between page loads and browsers.

* Adds a new preferences persistence API.
* Saves editor preferences in user meta instead of in browser's local storage.

Why?
Due to the transient nature of browser storage, this persistence is not as sticky as it is expected to be, including: switching browsers (unique storage between browsers), or using private browsing tabs (storage cleared between sessions), or the same user across a network of sites (storage unique by domain).

This is a backport from Gutenberg.[https://github.com/WordPress/gutenberg/pull/39795 See WordPress/gutenberg PR 39795].

Props talldanwp, youknowriad, noisysocks, mamaduka, costdev, ironprogrammer, hellofromTonya.
See #56467.
Built from https://develop.svn.wordpress.org/trunk@54182


git-svn-id: http://core.svn.wordpress.org/trunk@53741 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2022-09-15 16:45:40 +00:00

406 lines
12 KiB
JavaScript

/******/ (function() { // webpackBootstrap
/******/ "use strict";
/******/ // The require scope
/******/ var __webpack_require__ = {};
/******/
/************************************************************************/
/******/ /* webpack/runtime/define property getters */
/******/ !function() {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = function(exports, definition) {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ }();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ !function() {
/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
/******/ }();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ !function() {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ }();
/******/
/************************************************************************/
var __webpack_exports__ = {};
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
"PreferenceToggleMenuItem": function() { return /* reexport */ PreferenceToggleMenuItem; },
"store": function() { return /* reexport */ store; }
});
// NAMESPACE OBJECT: ./node_modules/@wordpress/preferences/build-module/store/actions.js
var actions_namespaceObject = {};
__webpack_require__.r(actions_namespaceObject);
__webpack_require__.d(actions_namespaceObject, {
"set": function() { return set; },
"setDefaults": function() { return setDefaults; },
"setPersistenceLayer": function() { return setPersistenceLayer; },
"toggle": function() { return toggle; }
});
// NAMESPACE OBJECT: ./node_modules/@wordpress/preferences/build-module/store/selectors.js
var selectors_namespaceObject = {};
__webpack_require__.r(selectors_namespaceObject);
__webpack_require__.d(selectors_namespaceObject, {
"get": function() { return get; }
});
;// CONCATENATED MODULE: external ["wp","element"]
var external_wp_element_namespaceObject = window["wp"]["element"];
;// CONCATENATED MODULE: external ["wp","data"]
var external_wp_data_namespaceObject = window["wp"]["data"];
;// CONCATENATED MODULE: external ["wp","components"]
var external_wp_components_namespaceObject = window["wp"]["components"];
;// CONCATENATED MODULE: external ["wp","i18n"]
var external_wp_i18n_namespaceObject = window["wp"]["i18n"];
;// CONCATENATED MODULE: external ["wp","primitives"]
var external_wp_primitives_namespaceObject = window["wp"]["primitives"];
;// CONCATENATED MODULE: ./node_modules/@wordpress/preferences/node_modules/@wordpress/icons/build-module/library/check.js
/**
* WordPress dependencies
*/
const check = (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24"
}, (0,external_wp_element_namespaceObject.createElement)(external_wp_primitives_namespaceObject.Path, {
d: "M16.7 7.1l-6.3 8.5-3.3-2.5-.9 1.2 4.5 3.4L17.9 8z"
}));
/* harmony default export */ var library_check = (check);
;// CONCATENATED MODULE: external ["wp","a11y"]
var external_wp_a11y_namespaceObject = window["wp"]["a11y"];
;// CONCATENATED MODULE: ./node_modules/@wordpress/preferences/build-module/store/reducer.js
/**
* WordPress dependencies
*/
/**
* Reducer returning the defaults for user preferences.
*
* This is kept intentionally separate from the preferences
* themselves so that defaults are not persisted.
*
* @param {Object} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Object} Updated state.
*/
function defaults() {
let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
let action = arguments.length > 1 ? arguments[1] : undefined;
if (action.type === 'SET_PREFERENCE_DEFAULTS') {
const {
scope,
defaults: values
} = action;
return { ...state,
[scope]: { ...state[scope],
...values
}
};
}
return state;
}
/**
* Higher order reducer that does the following:
* - Merges any data from the persistence layer into the state when the
* `SET_PERSISTENCE_LAYER` action is received.
* - Passes any preferences changes to the persistence layer.
*
* @param {Function} reducer The preferences reducer.
*
* @return {Function} The enhanced reducer.
*/
function withPersistenceLayer(reducer) {
let persistenceLayer;
return (state, action) => {
// Setup the persistence layer, and return the persisted data
// as the state.
if (action.type === 'SET_PERSISTENCE_LAYER') {
const {
persistenceLayer: persistence,
persistedData
} = action;
persistenceLayer = persistence;
return persistedData;
}
const nextState = reducer(state, action);
if (action.type === 'SET_PREFERENCE_VALUE') {
var _persistenceLayer;
(_persistenceLayer = persistenceLayer) === null || _persistenceLayer === void 0 ? void 0 : _persistenceLayer.set(nextState);
}
return nextState;
};
}
/**
* Reducer returning the user preferences.
*
* @param {Object} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Object} Updated state.
*/
const preferences = withPersistenceLayer(function () {
let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
let action = arguments.length > 1 ? arguments[1] : undefined;
if (action.type === 'SET_PREFERENCE_VALUE') {
const {
scope,
name,
value
} = action;
return { ...state,
[scope]: { ...state[scope],
[name]: value
}
};
}
return state;
});
/* harmony default export */ var reducer = ((0,external_wp_data_namespaceObject.combineReducers)({
defaults,
preferences
}));
;// CONCATENATED MODULE: ./node_modules/@wordpress/preferences/build-module/store/actions.js
/**
* Returns an action object used in signalling that a preference should be
* toggled.
*
* @param {string} scope The preference scope (e.g. core/edit-post).
* @param {string} name The preference name.
*/
function toggle(scope, name) {
return function (_ref) {
let {
select,
dispatch
} = _ref;
const currentValue = select.get(scope, name);
dispatch.set(scope, name, !currentValue);
};
}
/**
* Returns an action object used in signalling that a preference should be set
* to a value
*
* @param {string} scope The preference scope (e.g. core/edit-post).
* @param {string} name The preference name.
* @param {*} value The value to set.
*
* @return {Object} Action object.
*/
function set(scope, name, value) {
return {
type: 'SET_PREFERENCE_VALUE',
scope,
name,
value
};
}
/**
* Returns an action object used in signalling that preference defaults should
* be set.
*
* @param {string} scope The preference scope (e.g. core/edit-post).
* @param {Object<string, *>} defaults A key/value map of preference names to values.
*
* @return {Object} Action object.
*/
function setDefaults(scope, defaults) {
return {
type: 'SET_PREFERENCE_DEFAULTS',
scope,
defaults
};
}
/** @typedef {() => Promise<Object>} WPPreferencesPersistenceLayerGet */
/** @typedef {(*) => void} WPPreferencesPersistenceLayerSet */
/**
* @typedef WPPreferencesPersistenceLayer
*
* @property {WPPreferencesPersistenceLayerGet} get An async function that gets data from the persistence layer.
* @property {WPPreferencesPersistenceLayerSet} set A function that sets data in the persistence layer.
*/
/**
* Sets the persistence layer.
*
* When a persistence layer is set, the preferences store will:
* - call `get` immediately and update the store state to the value returned.
* - call `set` with all preferences whenever a preference changes value.
*
* `setPersistenceLayer` should ideally be dispatched at the start of an
* application's lifecycle, before any other actions have been dispatched to
* the preferences store.
*
* @param {WPPreferencesPersistenceLayer} persistenceLayer The persistence layer.
*
* @return {Object} Action object.
*/
async function setPersistenceLayer(persistenceLayer) {
const persistedData = await persistenceLayer.get();
return {
type: 'SET_PERSISTENCE_LAYER',
persistenceLayer,
persistedData
};
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/preferences/build-module/store/selectors.js
/**
* Returns a boolean indicating whether a prefer is active for a particular
* scope.
*
* @param {Object} state The store state.
* @param {string} scope The scope of the feature (e.g. core/edit-post).
* @param {string} name The name of the feature.
*
* @return {*} Is the feature enabled?
*/
function get(state, scope, name) {
var _state$preferences$sc, _state$defaults$scope;
const value = (_state$preferences$sc = state.preferences[scope]) === null || _state$preferences$sc === void 0 ? void 0 : _state$preferences$sc[name];
return value !== undefined ? value : (_state$defaults$scope = state.defaults[scope]) === null || _state$defaults$scope === void 0 ? void 0 : _state$defaults$scope[name];
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/preferences/build-module/store/constants.js
/**
* The identifier for the data store.
*
* @type {string}
*/
const STORE_NAME = 'core/preferences';
;// CONCATENATED MODULE: ./node_modules/@wordpress/preferences/build-module/store/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
/**
* Store definition for the interface namespace.
*
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore
*
* @type {Object}
*/
const store = (0,external_wp_data_namespaceObject.createReduxStore)(STORE_NAME, {
reducer: reducer,
actions: actions_namespaceObject,
selectors: selectors_namespaceObject
});
(0,external_wp_data_namespaceObject.register)(store);
;// CONCATENATED MODULE: ./node_modules/@wordpress/preferences/build-module/components/preference-toggle-menu-item/index.js
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
function PreferenceToggleMenuItem(_ref) {
let {
scope,
name,
label,
info,
messageActivated,
messageDeactivated,
shortcut
} = _ref;
const isActive = (0,external_wp_data_namespaceObject.useSelect)(select => !!select(store).get(scope, name), [name]);
const {
toggle
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const speakMessage = () => {
if (isActive) {
const message = messageDeactivated || (0,external_wp_i18n_namespaceObject.sprintf)(
/* translators: %s: preference name, e.g. 'Fullscreen mode' */
(0,external_wp_i18n_namespaceObject.__)('Preference deactivated - %s'), label);
(0,external_wp_a11y_namespaceObject.speak)(message);
} else {
const message = messageActivated || (0,external_wp_i18n_namespaceObject.sprintf)(
/* translators: %s: preference name, e.g. 'Fullscreen mode' */
(0,external_wp_i18n_namespaceObject.__)('Preference activated - %s'), label);
(0,external_wp_a11y_namespaceObject.speak)(message);
}
};
return (0,external_wp_element_namespaceObject.createElement)(external_wp_components_namespaceObject.MenuItem, {
icon: isActive && library_check,
isSelected: isActive,
onClick: () => {
toggle(scope, name);
speakMessage();
},
role: "menuitemcheckbox",
info: info,
shortcut: shortcut
}, label);
}
;// CONCATENATED MODULE: ./node_modules/@wordpress/preferences/build-module/components/index.js
;// CONCATENATED MODULE: ./node_modules/@wordpress/preferences/build-module/index.js
(window.wp = window.wp || {}).preferences = __webpack_exports__;
/******/ })()
;