(dv, type)
| 133 | } |
| 134 | |
| 135 | function syncScroll(dv, type) { |
| 136 | // Change handler will do a refresh after a timeout when diff is out of date |
| 137 | if (dv.diffOutOfDate) return false; |
| 138 | if (!dv.lockScroll) return true; |
| 139 | var editor, other, now = +new Date; |
| 140 | if (type == DIFF_INSERT) { editor = dv.edit; other = dv.orig; } |
| 141 | else { editor = dv.orig; other = dv.edit; } |
| 142 | // Don't take action if the position of this editor was recently set |
| 143 | // (to prevent feedback loops) |
| 144 | if (editor.state.scrollSetBy == dv && (editor.state.scrollSetAt || 0) + 50 > now) return false; |
| 145 | |
| 146 | var sInfo = editor.getScrollInfo(); |
| 147 | if (dv.mv.options.connect == "align") { |
| 148 | targetPos = sInfo.top; |
| 149 | } else { |
| 150 | var halfScreen = .5 * sInfo.clientHeight, midY = sInfo.top + halfScreen; |
| 151 | var mid = editor.lineAtHeight(midY, "local"); |
| 152 | var around = chunkBoundariesAround(dv.chunks, mid, type == DIFF_INSERT); |
| 153 | var off = getOffsets(editor, type == DIFF_INSERT ? around.edit : around.orig); |
| 154 | var offOther = getOffsets(other, type == DIFF_INSERT ? around.orig : around.edit); |
| 155 | var ratio = (midY - off.top) / (off.bot - off.top); |
| 156 | var targetPos = (offOther.top - halfScreen) + ratio * (offOther.bot - offOther.top); |
| 157 | |
| 158 | var botDist, mix; |
| 159 | // Some careful tweaking to make sure no space is left out of view |
| 160 | // when scrolling to top or bottom. |
| 161 | if (targetPos > sInfo.top && (mix = sInfo.top / halfScreen) < 1) { |
| 162 | targetPos = targetPos * mix + sInfo.top * (1 - mix); |
| 163 | } else if ((botDist = sInfo.height - sInfo.clientHeight - sInfo.top) < halfScreen) { |
| 164 | var otherInfo = other.getScrollInfo(); |
| 165 | var botDistOther = otherInfo.height - otherInfo.clientHeight - targetPos; |
| 166 | if (botDistOther > botDist && (mix = botDist / halfScreen) < 1) |
| 167 | targetPos = targetPos * mix + (otherInfo.height - otherInfo.clientHeight - botDist) * (1 - mix); |
| 168 | } |
| 169 | } |
| 170 | |
| 171 | other.scrollTo(sInfo.left, targetPos); |
| 172 | other.state.scrollSetAt = now; |
| 173 | other.state.scrollSetBy = dv; |
| 174 | return true; |
| 175 | } |
| 176 | |
| 177 | function getOffsets(editor, around) { |
| 178 | var bot = around.after; |
no test coverage detected