UNPKG

@wordpress/editor

Version:
198 lines (190 loc) 6.87 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _element = require("@wordpress/element"); var _compose = require("@wordpress/compose"); var _data = require("@wordpress/data"); var _i18n = require("@wordpress/i18n"); var _blocks = require("@wordpress/blocks"); var _notices = require("@wordpress/notices"); var _autosaveMonitor = _interopRequireDefault(require("../autosave-monitor")); var _localAutosave = require("../../store/local-autosave"); var _store = require("../../store"); var _jsxRuntime = require("react/jsx-runtime"); /** * WordPress dependencies */ /** * Internal dependencies */ const requestIdleCallback = window.requestIdleCallback ? window.requestIdleCallback : window.requestAnimationFrame; let hasStorageSupport; /** * Function which returns true if the current environment supports browser * sessionStorage, or false otherwise. The result of this function is cached and * reused in subsequent invocations. */ const hasSessionStorageSupport = () => { if (hasStorageSupport !== undefined) { return hasStorageSupport; } try { // Private Browsing in Safari 10 and earlier will throw an error when // attempting to set into sessionStorage. The test here is intentional in // causing a thrown error as condition bailing from local autosave. window.sessionStorage.setItem('__wpEditorTestSessionStorage', ''); window.sessionStorage.removeItem('__wpEditorTestSessionStorage'); hasStorageSupport = true; } catch { hasStorageSupport = false; } return hasStorageSupport; }; /** * Custom hook which manages the creation of a notice prompting the user to * restore a local autosave, if one exists. */ function useAutosaveNotice() { const { postId, isEditedPostNew, hasRemoteAutosave } = (0, _data.useSelect)(select => ({ postId: select(_store.store).getCurrentPostId(), isEditedPostNew: select(_store.store).isEditedPostNew(), hasRemoteAutosave: !!select(_store.store).getEditorSettings().autosave }), []); const { getEditedPostAttribute } = (0, _data.useSelect)(_store.store); const { createWarningNotice, removeNotice } = (0, _data.useDispatch)(_notices.store); const { editPost, resetEditorBlocks } = (0, _data.useDispatch)(_store.store); (0, _element.useEffect)(() => { let localAutosave = (0, _localAutosave.localAutosaveGet)(postId, isEditedPostNew); if (!localAutosave) { return; } try { localAutosave = JSON.parse(localAutosave); } catch { // Not usable if it can't be parsed. return; } const { post_title: title, content, excerpt } = localAutosave; const edits = { title, content, excerpt }; { // Only display a notice if there is a difference between what has been // saved and that which is stored in sessionStorage. const hasDifference = Object.keys(edits).some(key => { return edits[key] !== getEditedPostAttribute(key); }); if (!hasDifference) { // If there is no difference, it can be safely ejected from storage. (0, _localAutosave.localAutosaveClear)(postId, isEditedPostNew); return; } } if (hasRemoteAutosave) { return; } const id = 'wpEditorAutosaveRestore'; createWarningNotice((0, _i18n.__)('The backup of this post in your browser is different from the version below.'), { id, actions: [{ label: (0, _i18n.__)('Restore the backup'), onClick() { const { content: editsContent, ...editsWithoutContent } = edits; editPost(editsWithoutContent); resetEditorBlocks((0, _blocks.parse)(edits.content)); removeNotice(id); } }] }); }, [isEditedPostNew, postId]); } /** * Custom hook which ejects a local autosave after a successful save occurs. */ function useAutosavePurge() { const { postId, isEditedPostNew, isDirty, isAutosaving, didError } = (0, _data.useSelect)(select => ({ postId: select(_store.store).getCurrentPostId(), isEditedPostNew: select(_store.store).isEditedPostNew(), isDirty: select(_store.store).isEditedPostDirty(), isAutosaving: select(_store.store).isAutosavingPost(), didError: select(_store.store).didPostSaveRequestFail() }), []); const lastIsDirtyRef = (0, _element.useRef)(isDirty); const lastIsAutosavingRef = (0, _element.useRef)(isAutosaving); (0, _element.useEffect)(() => { if (!didError && (lastIsAutosavingRef.current && !isAutosaving || lastIsDirtyRef.current && !isDirty)) { (0, _localAutosave.localAutosaveClear)(postId, isEditedPostNew); } lastIsDirtyRef.current = isDirty; lastIsAutosavingRef.current = isAutosaving; }, [isDirty, isAutosaving, didError]); // Once the isEditedPostNew changes from true to false, let's clear the auto-draft autosave. const wasEditedPostNew = (0, _compose.usePrevious)(isEditedPostNew); const prevPostId = (0, _compose.usePrevious)(postId); (0, _element.useEffect)(() => { if (prevPostId === postId && wasEditedPostNew && !isEditedPostNew) { (0, _localAutosave.localAutosaveClear)(postId, true); } }, [isEditedPostNew, postId]); } function LocalAutosaveMonitor() { const { autosave } = (0, _data.useDispatch)(_store.store); const deferredAutosave = (0, _element.useCallback)(() => { requestIdleCallback(() => autosave({ local: true })); }, []); useAutosaveNotice(); useAutosavePurge(); const localAutosaveInterval = (0, _data.useSelect)(select => select(_store.store).getEditorSettings().localAutosaveInterval, []); return /*#__PURE__*/(0, _jsxRuntime.jsx)(_autosaveMonitor.default, { interval: localAutosaveInterval, autosave: deferredAutosave }); } /** * Monitors local autosaves of a post in the editor. * It uses several hooks and functions to manage autosave behavior: * - `useAutosaveNotice` hook: Manages the creation of a notice prompting the user to restore a local autosave, if one exists. * - `useAutosavePurge` hook: Ejects a local autosave after a successful save occurs. * - `hasSessionStorageSupport` function: Checks if the current environment supports browser sessionStorage. * - `LocalAutosaveMonitor` component: Uses the `AutosaveMonitor` component to perform autosaves at a specified interval. * * The module also checks for sessionStorage support and conditionally exports the `LocalAutosaveMonitor` component based on that. * * @module LocalAutosaveMonitor */ var _default = exports.default = (0, _compose.ifCondition)(hasSessionStorageSupport)(LocalAutosaveMonitor); //# sourceMappingURL=index.js.map