| 321 | } |
| 322 | |
| 323 | move(start, end, index) { |
| 324 | start = start + this.offset; |
| 325 | end = end + this.offset; |
| 326 | index = index + this.offset; |
| 327 | |
| 328 | if (index >= start && index <= end) throw new Error('Cannot move a selection inside itself'); |
| 329 | |
| 330 | if (DEBUG) this.stats.time('move'); |
| 331 | |
| 332 | this._split(start); |
| 333 | this._split(end); |
| 334 | this._split(index); |
| 335 | |
| 336 | const first = this.byStart[start]; |
| 337 | const last = this.byEnd[end]; |
| 338 | |
| 339 | const oldLeft = first.previous; |
| 340 | const oldRight = last.next; |
| 341 | |
| 342 | const newRight = this.byStart[index]; |
| 343 | if (!newRight && last === this.lastChunk) return this; |
| 344 | const newLeft = newRight ? newRight.previous : this.lastChunk; |
| 345 | |
| 346 | if (oldLeft) oldLeft.next = oldRight; |
| 347 | if (oldRight) oldRight.previous = oldLeft; |
| 348 | |
| 349 | if (newLeft) newLeft.next = first; |
| 350 | if (newRight) newRight.previous = last; |
| 351 | |
| 352 | if (!first.previous) this.firstChunk = last.next; |
| 353 | if (!last.next) { |
| 354 | this.lastChunk = first.previous; |
| 355 | this.lastChunk.next = null; |
| 356 | } |
| 357 | |
| 358 | first.previous = newLeft; |
| 359 | last.next = newRight || null; |
| 360 | |
| 361 | if (!newLeft) this.firstChunk = first; |
| 362 | if (!newRight) this.lastChunk = last; |
| 363 | |
| 364 | if (DEBUG) this.stats.timeEnd('move'); |
| 365 | return this; |
| 366 | } |
| 367 | |
| 368 | overwrite(start, end, content, options) { |
| 369 | options = options || {}; |