(pos: Position)
| 221 | } |
| 222 | |
| 223 | function restore(pos: Position) { |
| 224 | const s = getSelection() |
| 225 | let startNode: Node | undefined, startOffset = 0 |
| 226 | let endNode: Node | undefined, endOffset = 0 |
| 227 | |
| 228 | if (!pos.dir) pos.dir = '->' |
| 229 | if (pos.start < 0) pos.start = 0 |
| 230 | if (pos.end < 0) pos.end = 0 |
| 231 | |
| 232 | // Flip start and end if the direction reversed |
| 233 | if (pos.dir == '<-') { |
| 234 | const { start, end } = pos |
| 235 | pos.start = end |
| 236 | pos.end = start |
| 237 | } |
| 238 | |
| 239 | let current = 0 |
| 240 | |
| 241 | visit(editor, el => { |
| 242 | if (el.nodeType !== Node.TEXT_NODE) return |
| 243 | |
| 244 | const len = (el.nodeValue || '').length |
| 245 | if (current + len > pos.start) { |
| 246 | if (!startNode) { |
| 247 | startNode = el |
| 248 | startOffset = pos.start - current |
| 249 | } |
| 250 | if (current + len > pos.end) { |
| 251 | endNode = el |
| 252 | endOffset = pos.end - current |
| 253 | return 'stop' |
| 254 | } |
| 255 | } |
| 256 | current += len |
| 257 | }) |
| 258 | |
| 259 | if (!startNode) startNode = editor, startOffset = editor.childNodes.length |
| 260 | if (!endNode) endNode = editor, endOffset = editor.childNodes.length |
| 261 | |
| 262 | // Flip back the selection |
| 263 | if (pos.dir == '<-') { |
| 264 | [startNode, startOffset, endNode, endOffset] = [endNode, endOffset, startNode, startOffset] |
| 265 | } |
| 266 | |
| 267 | { |
| 268 | // If nodes not editable, create a text node. |
| 269 | const startEl = uneditable(startNode) |
| 270 | if (startEl) { |
| 271 | const node = document.createTextNode('') |
| 272 | startEl.parentNode?.insertBefore(node, startEl) |
| 273 | startNode = node |
| 274 | startOffset = 0 |
| 275 | } |
| 276 | const endEl = uneditable(endNode) |
| 277 | if (endEl) { |
| 278 | const node = document.createTextNode('') |
| 279 | endEl.parentNode?.insertBefore(node, endEl) |
| 280 | endNode = node |
no test coverage detected