Index: trunk/extensions/VisualEditor/modules/ve/ce/ve.es.Surface.js |
— | — | @@ -116,6 +116,54 @@ |
117 | 117 | } |
118 | 118 | }; |
119 | 119 | |
| 120 | + |
| 121 | +ve.es.Surface.prototype.showCursorAt = function( offset ) { |
| 122 | + var $node = this.documentView.getNodeFromOffset( offset ).$; |
| 123 | + var current = [$node.contents(), 0]; |
| 124 | + var stack = [current]; |
| 125 | + var node; |
| 126 | + var localOffset; |
| 127 | + |
| 128 | + var index = 1 + this.documentView.getOffsetFromNode( $node.data('view') ); |
| 129 | + |
| 130 | + while ( stack.length > 0 ) { |
| 131 | + if ( current[1] >= current[0].length ) { |
| 132 | + stack.pop(); |
| 133 | + current = stack[ stack.length - 1 ]; |
| 134 | + continue; |
| 135 | + } |
| 136 | + var item = current[0][current[1]]; |
| 137 | + var $item = current[0].eq( current[1] ); |
| 138 | + |
| 139 | + if ( item.nodeType === 3 ) { |
| 140 | + var length = item.textContent.length; |
| 141 | + if ( offset >= index && offset <= index + length ) { |
| 142 | + node = item; |
| 143 | + localOffset = offset - index; |
| 144 | + } else { |
| 145 | + index += length; |
| 146 | + } |
| 147 | + } else if ( item.nodeType === 1 ) { |
| 148 | + if ( $( item ).attr('contentEditable') === "false" ) { |
| 149 | + index += 1; |
| 150 | + } else { |
| 151 | + stack.push( [$item.contents(), 0] ); |
| 152 | + current[1]++; |
| 153 | + current = stack[stack.length-1]; |
| 154 | + continue; |
| 155 | + } |
| 156 | + } |
| 157 | + current[1]++; |
| 158 | + } |
| 159 | + var range = document.createRange(); |
| 160 | + range.collapsed = true; |
| 161 | + range.setStart(node, localOffset); |
| 162 | + |
| 163 | + var sel = window.getSelection(); |
| 164 | + sel.removeAllRanges(); |
| 165 | + sel.addRange(range); |
| 166 | +}; |
| 167 | + |
120 | 168 | /* Inheritance */ |
121 | 169 | |
122 | 170 | ve.extendClass( ve.es.Surface, ve.EventEmitter ); |