| 12596 | } |
| 12597 | |
| 12598 | function locateNodeInLineView(lineView, node, offset) { |
| 12599 | var wrapper = lineView.text.firstChild, |
| 12600 | bad = false |
| 12601 | if (!node || !contains(wrapper, node)) { |
| 12602 | return badPos(Pos(lineNo(lineView.line), 0), true) |
| 12603 | } |
| 12604 | if (node == wrapper) { |
| 12605 | bad = true |
| 12606 | node = wrapper.childNodes[offset] |
| 12607 | offset = 0 |
| 12608 | if (!node) { |
| 12609 | var line = lineView.rest ? lst(lineView.rest) : lineView.line |
| 12610 | return badPos(Pos(lineNo(line), line.text.length), bad) |
| 12611 | } |
| 12612 | } |
| 12613 | |
| 12614 | var textNode = node.nodeType == 3 ? node : null, |
| 12615 | topNode = node |
| 12616 | if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) { |
| 12617 | textNode = node.firstChild |
| 12618 | if (offset) { |
| 12619 | offset = textNode.nodeValue.length |
| 12620 | } |
| 12621 | } |
| 12622 | while (topNode.parentNode != wrapper) { |
| 12623 | topNode = topNode.parentNode |
| 12624 | } |
| 12625 | var measure = lineView.measure, |
| 12626 | maps = measure.maps |
| 12627 | |
| 12628 | function find(textNode, topNode, offset) { |
| 12629 | for (var i = -1; i < (maps ? maps.length : 0); i++) { |
| 12630 | var map$$1 = i < 0 ? measure.map : maps[i] |
| 12631 | for (var j = 0; j < map$$1.length; j += 3) { |
| 12632 | var curNode = map$$1[j + 2] |
| 12633 | if (curNode == textNode || curNode == topNode) { |
| 12634 | var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]) |
| 12635 | var ch = map$$1[j] + offset |
| 12636 | if (offset < 0 || curNode != textNode) { |
| 12637 | ch = map$$1[j + (offset ? 1 : 0)] |
| 12638 | } |
| 12639 | return Pos(line, ch) |
| 12640 | } |
| 12641 | } |
| 12642 | } |
| 12643 | } |
| 12644 | var found = find(textNode, topNode, offset) |
| 12645 | if (found) { |
| 12646 | return badPos(found, bad) |
| 12647 | } |
| 12648 | |
| 12649 | // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems |
| 12650 | for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) { |
| 12651 | found = find(after, after.firstChild, 0) |
| 12652 | if (found) { |
| 12653 | return badPos(Pos(found.line, found.ch - dist), bad) |
| 12654 | } else { |
| 12655 | dist += after.textContent.length |