(cm, changes, visible, forced)
| 458 | // determine which DOM updates have to be made, and makes the |
| 459 | // updates. |
| 460 | function updateDisplayInner(cm, changes, visible, forced) { |
| 461 | var display = cm.display, doc = cm.doc; |
| 462 | if (!display.wrapper.offsetWidth) { |
| 463 | display.showingFrom = display.showingTo = doc.first; |
| 464 | display.viewOffset = 0; |
| 465 | return; |
| 466 | } |
| 467 | |
| 468 | // Bail out if the visible area is already rendered and nothing changed. |
| 469 | if (!forced && changes.length == 0 && |
| 470 | visible.from > display.showingFrom && visible.to < display.showingTo) |
| 471 | return; |
| 472 | |
| 473 | if (maybeUpdateLineNumberWidth(cm)) |
| 474 | changes = [{from: doc.first, to: doc.first + doc.size}]; |
| 475 | var gutterW = display.sizer.style.marginLeft = display.gutters.offsetWidth + "px"; |
| 476 | display.scrollbarH.style.left = cm.options.fixedGutter ? gutterW : "0"; |
| 477 | |
| 478 | // Used to determine which lines need their line numbers updated |
| 479 | var positionsChangedFrom = Infinity; |
| 480 | if (cm.options.lineNumbers) |
| 481 | for (var i = 0; i < changes.length; ++i) |
| 482 | if (changes[i].diff && changes[i].from < positionsChangedFrom) { positionsChangedFrom = changes[i].from; } |
| 483 | |
| 484 | var end = doc.first + doc.size; |
| 485 | var from = Math.max(visible.from - cm.options.viewportMargin, doc.first); |
| 486 | var to = Math.min(end, visible.to + cm.options.viewportMargin); |
| 487 | if (display.showingFrom < from && from - display.showingFrom < 20) from = Math.max(doc.first, display.showingFrom); |
| 488 | if (display.showingTo > to && display.showingTo - to < 20) to = Math.min(end, display.showingTo); |
| 489 | if (sawCollapsedSpans) { |
| 490 | from = lineNo(visualLine(doc, getLine(doc, from))); |
| 491 | while (to < end && lineIsHidden(doc, getLine(doc, to))) ++to; |
| 492 | } |
| 493 | |
| 494 | // Create a range of theoretically intact lines, and punch holes |
| 495 | // in that using the change info. |
| 496 | var intact = [{from: Math.max(display.showingFrom, doc.first), |
| 497 | to: Math.min(display.showingTo, end)}]; |
| 498 | if (intact[0].from >= intact[0].to) intact = []; |
| 499 | else intact = computeIntact(intact, changes); |
| 500 | // When merged lines are present, we might have to reduce the |
| 501 | // intact ranges because changes in continued fragments of the |
| 502 | // intact lines do require the lines to be redrawn. |
| 503 | if (sawCollapsedSpans) |
| 504 | for (var i = 0; i < intact.length; ++i) { |
| 505 | var range = intact[i], merged; |
| 506 | while (merged = collapsedSpanAtEnd(getLine(doc, range.to - 1))) { |
| 507 | var newTo = merged.find().from.line; |
| 508 | if (newTo > range.from) range.to = newTo; |
| 509 | else { intact.splice(i--, 1); break; } |
| 510 | } |
| 511 | } |
| 512 | |
| 513 | // Clip off the parts that won't be visible |
| 514 | var intactLines = 0; |
| 515 | for (var i = 0; i < intact.length; ++i) { |
| 516 | var range = intact[i]; |
| 517 | if (range.from < from) range.from = from; |
no test coverage detected