(cm, line)
| 972 | } |
| 973 | |
| 974 | function measureLineInner(cm, line) { |
| 975 | var display = cm.display, measure = emptyArray(line.text.length); |
| 976 | var pre = lineContent(cm, line, measure); |
| 977 | |
| 978 | // IE does not cache element positions of inline elements between |
| 979 | // calls to getBoundingClientRect. This makes the loop below, |
| 980 | // which gathers the positions of all the characters on the line, |
| 981 | // do an amount of layout work quadratic to the number of |
| 982 | // characters. When line wrapping is off, we try to improve things |
| 983 | // by first subdividing the line into a bunch of inline blocks, so |
| 984 | // that IE can reuse most of the layout information from caches |
| 985 | // for those blocks. This does interfere with line wrapping, so it |
| 986 | // doesn't work when wrapping is on, but in that case the |
| 987 | // situation is slightly better, since IE does cache line-wrapping |
| 988 | // information and only recomputes per-line. |
| 989 | if (ie && !ie_lt8 && !cm.options.lineWrapping && pre.childNodes.length > 100) { |
| 990 | var fragment = document.createDocumentFragment(); |
| 991 | var chunk = 10, n = pre.childNodes.length; |
| 992 | for (var i = 0, chunks = Math.ceil(n / chunk); i < chunks; ++i) { |
| 993 | var wrap = elt("div", null, null, "display: inline-block"); |
| 994 | for (var j = 0; j < chunk && n; ++j) { |
| 995 | wrap.appendChild(pre.firstChild); |
| 996 | --n; |
| 997 | } |
| 998 | fragment.appendChild(wrap); |
| 999 | } |
| 1000 | pre.appendChild(fragment); |
| 1001 | } |
| 1002 | |
| 1003 | removeChildrenAndAdd(display.measure, pre); |
| 1004 | |
| 1005 | var outer = getRect(display.lineDiv); |
| 1006 | var vranges = [], data = emptyArray(line.text.length), maxBot = pre.offsetHeight; |
| 1007 | // Work around an IE7/8 bug where it will sometimes have randomly |
| 1008 | // replaced our pre with a clone at this point. |
| 1009 | if (ie_lt9 && display.measure.first != pre) |
| 1010 | removeChildrenAndAdd(display.measure, pre); |
| 1011 | |
| 1012 | for (var i = 0, cur; i < measure.length; ++i) if (cur = measure[i]) { |
| 1013 | var size = getRect(cur); |
| 1014 | var top = Math.max(0, size.top - outer.top), bot = Math.min(size.bottom - outer.top, maxBot); |
| 1015 | for (var j = 0; j < vranges.length; j += 2) { |
| 1016 | var rtop = vranges[j], rbot = vranges[j+1]; |
| 1017 | if (rtop > bot || rbot < top) continue; |
| 1018 | if (rtop <= top && rbot >= bot || |
| 1019 | top <= rtop && bot >= rbot || |
| 1020 | Math.min(bot, rbot) - Math.max(top, rtop) >= (bot - top) >> 1) { |
| 1021 | vranges[j] = Math.min(top, rtop); |
| 1022 | vranges[j+1] = Math.max(bot, rbot); |
| 1023 | break; |
| 1024 | } |
| 1025 | } |
| 1026 | if (j == vranges.length) vranges.push(top, bot); |
| 1027 | var right = size.right; |
| 1028 | if (cur.measureRight) right = getRect(cur.measureRight).left; |
| 1029 | data[i] = {left: size.left - outer.left, right: right - outer.left, top: j}; |
| 1030 | } |
| 1031 | for (var i = 0, cur; i < data.length; ++i) if (cur = data[i]) { |
no test coverage detected