UNPKG

@wordpress/editor

Version:
124 lines (123 loc) 3.78 kB
// packages/editor/src/components/post-text-editor/utils.js import { diffChars } from "diff/lib/diff/character.js"; import { diffLines } from "diff/lib/diff/line.js"; var STRING_TOO_LARGE_THRESHOLD = 1e3; function getDiff(oldValue, newValue) { const maxStringLength = Math.max(oldValue.length, newValue.length); if (maxStringLength <= STRING_TOO_LARGE_THRESHOLD) { return diffChars(oldValue, newValue); } let start = 0; const minStringLength = Math.min(oldValue.length, newValue.length); while (start < minStringLength && oldValue[start] === newValue[start]) { start++; } let oldEnd = oldValue.length; let newEnd = newValue.length; while (oldEnd > start && newEnd > start && oldValue[oldEnd - 1] === newValue[newEnd - 1]) { oldEnd--; newEnd--; } const oldChangedValue = oldValue.slice(start, oldEnd); const newChangedValue = newValue.slice(start, newEnd); const maxChangedStringLength = Math.max( oldChangedValue.length, newChangedValue.length ); let changes; if (maxChangedStringLength <= STRING_TOO_LARGE_THRESHOLD) { changes = diffChars(oldChangedValue, newChangedValue); } else { changes = diffLines(oldChangedValue, newChangedValue); } if (start > 0) { changes.unshift({ value: oldValue.slice(0, start) }); } if (oldEnd < oldValue.length) { changes.push({ value: oldValue.slice(oldEnd) }); } return changes; } function clampCursorPosition(position, value) { return Math.max(0, Math.min(value.length, position)); } function getCursorOffsetFromCommonTextBeforeCursor(oldValue, newValue, position) { const oldValueBeforeCursor = oldValue.slice(0, position); let low = 1; let high = oldValueBeforeCursor.length; let cursorOffset; while (low <= high) { const length = Math.floor((low + high) / 2); const index = newValue.indexOf( oldValueBeforeCursor.slice(oldValueBeforeCursor.length - length) ); if (index === -1) { high = length - 1; } else { cursorOffset = index + length; low = length + 1; } } return cursorOffset; } function adjustPosition(position, changes, oldValue, newValue) { let oldIndex = 0; let newIndex = 0; let adjustedPosition = position; for (let i = 0; i < changes.length; i++) { const change = changes[i]; if (!change.added && !change.removed) { oldIndex += change.value.length; newIndex += change.value.length; continue; } const oldStart = oldIndex; const newStart = newIndex; let oldLength = 0; let newLength = 0; while (i < changes.length && (changes[i].added || changes[i].removed)) { if (changes[i].removed) { oldLength += changes[i].value.length; } else { newLength += changes[i].value.length; } i++; } i--; const oldEnd = oldStart + oldLength; const newEnd = newStart + newLength; if (position < oldStart) { break; } if (oldLength === 0) { adjustedPosition += newLength; } else if (position <= oldEnd) { const cursorOffset = getCursorOffsetFromCommonTextBeforeCursor( oldValue.slice(oldStart, oldEnd), newValue.slice(newStart, newEnd), position - oldStart ); adjustedPosition = cursorOffset === void 0 ? newEnd : newStart + cursorOffset; break; } else { adjustedPosition += newLength - oldLength; } oldIndex += oldLength; newIndex += newLength; } return clampCursorPosition(adjustedPosition, newValue); } function getAdjustedCursorPosition(position, oldValue, newValue) { return adjustPosition( position, getDiff(oldValue, newValue), oldValue, newValue ); } export { adjustPosition, getAdjustedCursorPosition, getDiff }; //# sourceMappingURL=utils.mjs.map