Index: trunk/extensions/VisualEditor/modules/es/views/es.SurfaceView.js |
— | — | @@ -230,105 +230,98 @@ |
231 | 231 | |
232 | 232 | es.SurfaceView.prototype.moveCursor = function( instruction ) { |
233 | 233 | this.selection.normalize(); |
234 | | - var offset; |
235 | | - if ( instruction === 'left') { |
236 | | - if ( !this.keyboard.keys.shift ) { |
237 | | - this.selection.from = this.selection.to = |
238 | | - this.documentView.getModel().getRelativeContentOffset( |
239 | | - this.selection.getLength() ? this.selection.start : this.selection.to, -1 |
240 | | - ); |
241 | | - this.documentView.clearSelection(); |
242 | | - this.showCursor(); |
243 | | - } else { |
244 | | - this.selection.to = this.documentView.getModel().getRelativeContentOffset( |
245 | | - this.selection.to, -1 |
246 | | - ); |
247 | | - this.documentView.drawSelection( this.selection ); |
248 | | - this.hideCursor(); |
249 | | - } |
250 | | - } else if ( instruction === 'right' ) { |
251 | | - if ( !this.keyboard.keys.shift ) { |
252 | | - this.selection.from = this.selection.to = |
253 | | - this.documentView.getModel().getRelativeContentOffset( |
254 | | - this.selection.getLength() ? this.selection.end : this.selection.to, 1 |
255 | | - ); |
256 | | - this.documentView.clearSelection(); |
257 | | - this.showCursor(); |
258 | | - } else { |
259 | | - this.selection.to = this.documentView.getModel().getRelativeContentOffset( |
260 | | - this.selection.to, 1 |
261 | | - ); |
262 | | - this.documentView.drawSelection( this.selection ); |
263 | | - this.hideCursor(); |
264 | | - } |
265 | | - } else if ( instruction === 'up' || instruction === 'down' ) { |
266 | | - var currentPosition = this.documentView.getRenderedPositionFromOffset( this.selection.to ); |
267 | 234 | |
268 | | - if ( this.cursor.initialLeft === null ) { |
269 | | - this.cursor.initialLeft = currentPosition.left; |
270 | | - } |
| 235 | + var from, to; |
271 | 236 | |
272 | | - var fakePosition = new es.Position( this.cursor.initialLeft, currentPosition.top ), |
273 | | - step, |
274 | | - edge, |
275 | | - i = 0; |
| 237 | + if ( instruction === 'up' || instruction === 'down' ) { |
| 238 | + /* |
| 239 | + * Looks for the in-document character position that would match up with the same horizontal |
| 240 | + * position - jumping a few pixels up/down at a time until we reach the next/previous line |
| 241 | + */ |
276 | 242 | |
277 | | - if ( instruction === 'up' ) { |
278 | | - step = -5; |
279 | | - edge = 0; |
280 | | - } else { |
281 | | - step = 5; |
282 | | - edge = this.documentView.getContentLength(); |
| 243 | + var position = this.documentView.getRenderedPositionFromOffset( this.selection.to ); |
| 244 | + if ( this.cursor.initialLeft === null ) { |
| 245 | + this.cursor.initialLeft = position.left; |
283 | 246 | } |
284 | 247 | |
| 248 | + var fakePosition = new es.Position( this.cursor.initialLeft, position.top ), |
| 249 | + i = 0, |
| 250 | + step = instruction === 'up' ? -5 : 5, |
| 251 | + top = this.$.position().top; |
| 252 | + |
285 | 253 | do { |
286 | 254 | fakePosition.top += ++i * step; |
287 | | - offset = this.documentView.getOffsetFromRenderedPosition( fakePosition ); |
288 | | - fakePosition = this.documentView.getRenderedPositionFromOffset( offset ); |
| 255 | + if ( fakePosition.top < top || fakePosition.top > top + this.dimensions.height ) { |
| 256 | + break; |
| 257 | + } |
| 258 | + fakePosition = this.documentView.getRenderedPositionFromOffset( |
| 259 | + this.documentView.getOffsetFromRenderedPosition( fakePosition ) |
| 260 | + ); |
289 | 261 | fakePosition.left = this.cursor.initialLeft; |
290 | | - } while ( currentPosition.top === fakePosition.top && offset !== edge ); |
| 262 | + } while ( position.top === fakePosition.top ); |
291 | 263 | |
| 264 | + to = this.documentView.getOffsetFromRenderedPosition( fakePosition ); |
292 | 265 | if ( !this.keyboard.keys.shift ) { |
293 | | - this.selection.from = this.selection.to = |
294 | | - this.documentView.getOffsetFromRenderedPosition( fakePosition ); |
295 | | - this.documentView.clearSelection(); |
296 | | - this.showCursor(); |
| 266 | + from = to; |
| 267 | + } |
| 268 | + |
| 269 | + } else if ( instruction === 'left' ) { |
| 270 | + this.cursor.initialLeft = null; |
| 271 | + if ( !this.keyboard.keys.shift ) { |
| 272 | + from = to = this.documentView.getModel().getRelativeContentOffset( |
| 273 | + this.selection.getLength() ? this.selection.start : this.selection.to, -1 ); |
297 | 274 | } else { |
298 | | - this.selection.to = this.documentView.getOffsetFromRenderedPosition( fakePosition ); |
299 | | - this.documentView.drawSelection( this.selection ); |
300 | | - this.hideCursor(); |
| 275 | + to = this.documentView.getModel().getRelativeContentOffset( this.selection.to, -1 ); |
301 | 276 | } |
| 277 | + } else if ( instruction === 'right' ) { |
| 278 | + this.cursor.initialLeft = null; |
| 279 | + if ( !this.keyboard.keys.shift ) { |
| 280 | + from = to = this.documentView.getModel().getRelativeContentOffset( |
| 281 | + this.selection.getLength() ? this.selection.end : this.selection.to, 1 ); |
| 282 | + } else { |
| 283 | + to = this.documentView.getModel().getRelativeContentOffset( this.selection.to, 1 ); |
| 284 | + } |
302 | 285 | } else if ( instruction === 'home' ) { |
303 | | - offset = this.documentView.getRenderedLineRangeFromOffset( |
304 | | - this.cursor.initialBias ? |
305 | | - this.documentView.getModel().getRelativeContentOffset( this.selection.to, -1 ) : |
306 | | - this.selection.to |
| 286 | + this.cursor.initialLeft = null; |
| 287 | + to = this.documentView.getRenderedLineRangeFromOffset( |
| 288 | + this.cursor.initialBias |
| 289 | + ? this.documentView.getModel().getRelativeContentOffset( this.selection.to, -1 ) |
| 290 | + : this.selection.to |
307 | 291 | ).start; |
308 | 292 | if ( !this.keyboard.keys.shift ) { |
309 | | - this.selection.from = this.selection.to = offset; |
310 | | - this.documentView.clearSelection(); |
311 | | - this.showCursor(); |
312 | | - } else { |
313 | | - this.selection.to = offset; |
314 | | - this.documentView.drawSelection( this.selection ); |
315 | | - this.hideCursor(); |
| 293 | + from = to; |
316 | 294 | } |
317 | 295 | } else if ( instruction === 'end' ) { |
318 | | - offset = this.documentView.getRenderedLineRangeFromOffset( |
319 | | - this.cursor.initialBias ? |
320 | | - this.documentView.getModel().getRelativeContentOffset( this.selection.to, -1 ) : |
321 | | - this.selection.to |
| 296 | + this.cursor.initialLeft = null; |
| 297 | + to = this.documentView.getRenderedLineRangeFromOffset( |
| 298 | + this.cursor.initialBias |
| 299 | + ? this.documentView.getModel().getRelativeContentOffset( this.selection.to, -1 ) |
| 300 | + : this.selection.to |
322 | 301 | ).end; |
323 | 302 | if ( !this.keyboard.keys.shift ) { |
324 | | - this.selection.from = this.selection.to = offset; |
| 303 | + from = to; |
| 304 | + } |
| 305 | + } |
| 306 | + |
| 307 | + if ( from === to ) { |
| 308 | + if ( this.selection.from !== this.selection.to ) { |
325 | 309 | this.documentView.clearSelection(); |
326 | | - this.showCursor(); |
327 | | - } else { |
328 | | - this.selection.to = offset; |
329 | | - this.documentView.drawSelection( this.selection ); |
330 | | - this.hideCursor(); |
331 | 310 | } |
| 311 | + this.selection.from = this.selection.to = to; |
| 312 | + } else { |
| 313 | + this.selection.to = to; |
| 314 | + this.documentView.drawSelection( this.selection ); |
332 | 315 | } |
| 316 | + |
| 317 | + if ( this.selection.from !== this.selection.to ) { |
| 318 | + this.hideCursor(); |
| 319 | + if(instruction === 'home') |
| 320 | + this.cursor.initialBias = false; |
| 321 | + else if(instruction === 'end') |
| 322 | + this.cursor.initialBias = true; |
| 323 | + } else { |
| 324 | + this.showCursor( instruction === 'end' ); |
| 325 | + } |
333 | 326 | }; |
334 | 327 | |
335 | 328 | /** |