| 1908 | } |
| 1909 | |
| 1910 | function locateNodeInLineView(lineView, node, offset) { |
| 1911 | var wrapper = lineView.text.firstChild, bad = false; |
| 1912 | if (!node || !contains(wrapper, node)) return badPos(Pos(lineNo(lineView.line), 0), true); |
| 1913 | if (node == wrapper) { |
| 1914 | bad = true; |
| 1915 | node = wrapper.childNodes[offset]; |
| 1916 | offset = 0; |
| 1917 | if (!node) { |
| 1918 | var line = lineView.rest ? lst(lineView.rest) : lineView.line; |
| 1919 | return badPos(Pos(lineNo(line), line.text.length), bad); |
| 1920 | } |
| 1921 | } |
| 1922 | |
| 1923 | var textNode = node.nodeType == 3 ? node : null, topNode = node; |
| 1924 | if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) { |
| 1925 | textNode = node.firstChild; |
| 1926 | if (offset) offset = textNode.nodeValue.length; |
| 1927 | } |
| 1928 | while (topNode.parentNode != wrapper) topNode = topNode.parentNode; |
| 1929 | var measure = lineView.measure, maps = measure.maps; |
| 1930 | |
| 1931 | function find(textNode, topNode, offset) { |
| 1932 | for (var i = -1; i < (maps ? maps.length : 0); i++) { |
| 1933 | var map = i < 0 ? measure.map : maps[i]; |
| 1934 | for (var j = 0; j < map.length; j += 3) { |
| 1935 | var curNode = map[j + 2]; |
| 1936 | if (curNode == textNode || curNode == topNode) { |
| 1937 | var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]); |
| 1938 | var ch = map[j] + offset; |
| 1939 | if (offset < 0 || curNode != textNode) ch = map[j + (offset ? 1 : 0)]; |
| 1940 | return Pos(line, ch); |
| 1941 | } |
| 1942 | } |
| 1943 | } |
| 1944 | } |
| 1945 | var found = find(textNode, topNode, offset); |
| 1946 | if (found) return badPos(found, bad); |
| 1947 | |
| 1948 | // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems |
| 1949 | for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) { |
| 1950 | found = find(after, after.firstChild, 0); |
| 1951 | if (found) |
| 1952 | return badPos(Pos(found.line, found.ch - dist), bad); |
| 1953 | else |
| 1954 | dist += after.textContent.length; |
| 1955 | } |
| 1956 | for (var before = topNode.previousSibling, dist = offset; before; before = before.previousSibling) { |
| 1957 | found = find(before, before.firstChild, -1); |
| 1958 | if (found) |
| 1959 | return badPos(Pos(found.line, found.ch + dist), bad); |
| 1960 | else |
| 1961 | dist += after.textContent.length; |
| 1962 | } |
| 1963 | } |
| 1964 | |
| 1965 | function domTextBetween(cm, from, to, fromLine, toLine) { |
| 1966 | var text = "", closing = false, lineSep = cm.doc.lineSeparator(); |