|
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 ; |