wp/wp-includes/js/dist/undo-manager.js
changeset 21 48c4eec2b7e6
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
       
     1 /******/ (() => { // webpackBootstrap
       
     2 /******/ 	"use strict";
       
     3 /******/ 	var __webpack_modules__ = ({
       
     4 
       
     5 /***/ 923:
       
     6 /***/ ((module) => {
       
     7 
       
     8 module.exports = window["wp"]["isShallowEqual"];
       
     9 
       
    10 /***/ })
       
    11 
       
    12 /******/ 	});
       
    13 /************************************************************************/
       
    14 /******/ 	// The module cache
       
    15 /******/ 	var __webpack_module_cache__ = {};
       
    16 /******/ 	
       
    17 /******/ 	// The require function
       
    18 /******/ 	function __webpack_require__(moduleId) {
       
    19 /******/ 		// Check if module is in cache
       
    20 /******/ 		var cachedModule = __webpack_module_cache__[moduleId];
       
    21 /******/ 		if (cachedModule !== undefined) {
       
    22 /******/ 			return cachedModule.exports;
       
    23 /******/ 		}
       
    24 /******/ 		// Create a new module (and put it into the cache)
       
    25 /******/ 		var module = __webpack_module_cache__[moduleId] = {
       
    26 /******/ 			// no module.id needed
       
    27 /******/ 			// no module.loaded needed
       
    28 /******/ 			exports: {}
       
    29 /******/ 		};
       
    30 /******/ 	
       
    31 /******/ 		// Execute the module function
       
    32 /******/ 		__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
       
    33 /******/ 	
       
    34 /******/ 		// Return the exports of the module
       
    35 /******/ 		return module.exports;
       
    36 /******/ 	}
       
    37 /******/ 	
       
    38 /************************************************************************/
       
    39 /******/ 	/* webpack/runtime/compat get default export */
       
    40 /******/ 	(() => {
       
    41 /******/ 		// getDefaultExport function for compatibility with non-harmony modules
       
    42 /******/ 		__webpack_require__.n = (module) => {
       
    43 /******/ 			var getter = module && module.__esModule ?
       
    44 /******/ 				() => (module['default']) :
       
    45 /******/ 				() => (module);
       
    46 /******/ 			__webpack_require__.d(getter, { a: getter });
       
    47 /******/ 			return getter;
       
    48 /******/ 		};
       
    49 /******/ 	})();
       
    50 /******/ 	
       
    51 /******/ 	/* webpack/runtime/define property getters */
       
    52 /******/ 	(() => {
       
    53 /******/ 		// define getter functions for harmony exports
       
    54 /******/ 		__webpack_require__.d = (exports, definition) => {
       
    55 /******/ 			for(var key in definition) {
       
    56 /******/ 				if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
       
    57 /******/ 					Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
       
    58 /******/ 				}
       
    59 /******/ 			}
       
    60 /******/ 		};
       
    61 /******/ 	})();
       
    62 /******/ 	
       
    63 /******/ 	/* webpack/runtime/hasOwnProperty shorthand */
       
    64 /******/ 	(() => {
       
    65 /******/ 		__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
       
    66 /******/ 	})();
       
    67 /******/ 	
       
    68 /******/ 	/* webpack/runtime/make namespace object */
       
    69 /******/ 	(() => {
       
    70 /******/ 		// define __esModule on exports
       
    71 /******/ 		__webpack_require__.r = (exports) => {
       
    72 /******/ 			if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
       
    73 /******/ 				Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
       
    74 /******/ 			}
       
    75 /******/ 			Object.defineProperty(exports, '__esModule', { value: true });
       
    76 /******/ 		};
       
    77 /******/ 	})();
       
    78 /******/ 	
       
    79 /************************************************************************/
       
    80 var __webpack_exports__ = {};
       
    81 // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
       
    82 (() => {
       
    83 __webpack_require__.r(__webpack_exports__);
       
    84 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
       
    85 /* harmony export */   createUndoManager: () => (/* binding */ createUndoManager)
       
    86 /* harmony export */ });
       
    87 /* harmony import */ var _wordpress_is_shallow_equal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(923);
       
    88 /* harmony import */ var _wordpress_is_shallow_equal__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_wordpress_is_shallow_equal__WEBPACK_IMPORTED_MODULE_0__);
       
    89 /**
       
    90  * WordPress dependencies
       
    91  */
       
    92 
       
    93 
       
    94 /** @typedef {import('./types').HistoryRecord}  HistoryRecord */
       
    95 /** @typedef {import('./types').HistoryChange}  HistoryChange */
       
    96 /** @typedef {import('./types').HistoryChanges} HistoryChanges */
       
    97 /** @typedef {import('./types').UndoManager} UndoManager */
       
    98 
       
    99 /**
       
   100  * Merge changes for a single item into a record of changes.
       
   101  *
       
   102  * @param {Record< string, HistoryChange >} changes1 Previous changes
       
   103  * @param {Record< string, HistoryChange >} changes2 NextChanges
       
   104  *
       
   105  * @return {Record< string, HistoryChange >} Merged changes
       
   106  */
       
   107 function mergeHistoryChanges(changes1, changes2) {
       
   108   /**
       
   109    * @type {Record< string, HistoryChange >}
       
   110    */
       
   111   const newChanges = {
       
   112     ...changes1
       
   113   };
       
   114   Object.entries(changes2).forEach(([key, value]) => {
       
   115     if (newChanges[key]) {
       
   116       newChanges[key] = {
       
   117         ...newChanges[key],
       
   118         to: value.to
       
   119       };
       
   120     } else {
       
   121       newChanges[key] = value;
       
   122     }
       
   123   });
       
   124   return newChanges;
       
   125 }
       
   126 
       
   127 /**
       
   128  * Adds history changes for a single item into a record of changes.
       
   129  *
       
   130  * @param {HistoryRecord}  record  The record to merge into.
       
   131  * @param {HistoryChanges} changes The changes to merge.
       
   132  */
       
   133 const addHistoryChangesIntoRecord = (record, changes) => {
       
   134   const existingChangesIndex = record?.findIndex(({
       
   135     id: recordIdentifier
       
   136   }) => {
       
   137     return typeof recordIdentifier === 'string' ? recordIdentifier === changes.id : _wordpress_is_shallow_equal__WEBPACK_IMPORTED_MODULE_0___default()(recordIdentifier, changes.id);
       
   138   });
       
   139   const nextRecord = [...record];
       
   140   if (existingChangesIndex !== -1) {
       
   141     // If the edit is already in the stack leave the initial "from" value.
       
   142     nextRecord[existingChangesIndex] = {
       
   143       id: changes.id,
       
   144       changes: mergeHistoryChanges(nextRecord[existingChangesIndex].changes, changes.changes)
       
   145     };
       
   146   } else {
       
   147     nextRecord.push(changes);
       
   148   }
       
   149   return nextRecord;
       
   150 };
       
   151 
       
   152 /**
       
   153  * Creates an undo manager.
       
   154  *
       
   155  * @return {UndoManager} Undo manager.
       
   156  */
       
   157 function createUndoManager() {
       
   158   /**
       
   159    * @type {HistoryRecord[]}
       
   160    */
       
   161   let history = [];
       
   162   /**
       
   163    * @type {HistoryRecord}
       
   164    */
       
   165   let stagedRecord = [];
       
   166   /**
       
   167    * @type {number}
       
   168    */
       
   169   let offset = 0;
       
   170   const dropPendingRedos = () => {
       
   171     history = history.slice(0, offset || undefined);
       
   172     offset = 0;
       
   173   };
       
   174   const appendStagedRecordToLatestHistoryRecord = () => {
       
   175     var _history$index;
       
   176     const index = history.length === 0 ? 0 : history.length - 1;
       
   177     let latestRecord = (_history$index = history[index]) !== null && _history$index !== void 0 ? _history$index : [];
       
   178     stagedRecord.forEach(changes => {
       
   179       latestRecord = addHistoryChangesIntoRecord(latestRecord, changes);
       
   180     });
       
   181     stagedRecord = [];
       
   182     history[index] = latestRecord;
       
   183   };
       
   184 
       
   185   /**
       
   186    * Checks whether a record is empty.
       
   187    * A record is considered empty if it the changes keep the same values.
       
   188    * Also updates to function values are ignored.
       
   189    *
       
   190    * @param {HistoryRecord} record
       
   191    * @return {boolean} Whether the record is empty.
       
   192    */
       
   193   const isRecordEmpty = record => {
       
   194     const filteredRecord = record.filter(({
       
   195       changes
       
   196     }) => {
       
   197       return Object.values(changes).some(({
       
   198         from,
       
   199         to
       
   200       }) => typeof from !== 'function' && typeof to !== 'function' && !_wordpress_is_shallow_equal__WEBPACK_IMPORTED_MODULE_0___default()(from, to));
       
   201     });
       
   202     return !filteredRecord.length;
       
   203   };
       
   204   return {
       
   205     /**
       
   206      * Record changes into the history.
       
   207      *
       
   208      * @param {HistoryRecord=} record   A record of changes to record.
       
   209      * @param {boolean}        isStaged Whether to immediately create an undo point or not.
       
   210      */
       
   211     addRecord(record, isStaged = false) {
       
   212       const isEmpty = !record || isRecordEmpty(record);
       
   213       if (isStaged) {
       
   214         if (isEmpty) {
       
   215           return;
       
   216         }
       
   217         record.forEach(changes => {
       
   218           stagedRecord = addHistoryChangesIntoRecord(stagedRecord, changes);
       
   219         });
       
   220       } else {
       
   221         dropPendingRedos();
       
   222         if (stagedRecord.length) {
       
   223           appendStagedRecordToLatestHistoryRecord();
       
   224         }
       
   225         if (isEmpty) {
       
   226           return;
       
   227         }
       
   228         history.push(record);
       
   229       }
       
   230     },
       
   231     undo() {
       
   232       if (stagedRecord.length) {
       
   233         dropPendingRedos();
       
   234         appendStagedRecordToLatestHistoryRecord();
       
   235       }
       
   236       const undoRecord = history[history.length - 1 + offset];
       
   237       if (!undoRecord) {
       
   238         return;
       
   239       }
       
   240       offset -= 1;
       
   241       return undoRecord;
       
   242     },
       
   243     redo() {
       
   244       const redoRecord = history[history.length + offset];
       
   245       if (!redoRecord) {
       
   246         return;
       
   247       }
       
   248       offset += 1;
       
   249       return redoRecord;
       
   250     },
       
   251     hasUndo() {
       
   252       return !!history[history.length - 1 + offset];
       
   253     },
       
   254     hasRedo() {
       
   255       return !!history[history.length + offset];
       
   256     }
       
   257   };
       
   258 }
       
   259 
       
   260 })();
       
   261 
       
   262 (window.wp = window.wp || {}).undoManager = __webpack_exports__;
       
   263 /******/ })()
       
   264 ;