Index: trunk/parsers/wikidom/lib/es/es.ParagraphBlock.js |
— | — | @@ -141,6 +141,10 @@ |
142 | 142 | return this.flow.getPosition( offset ); |
143 | 143 | }; |
144 | 144 | |
| 145 | +es.ParagraphBlock.prototype.getLineIndex = function( offset ) { |
| 146 | + return this.flow.getLineIndex( offset ); |
| 147 | +}; |
| 148 | + |
145 | 149 | /** |
146 | 150 | * Gets the start and end points of the word closest a given offset. |
147 | 151 | * |
Index: trunk/parsers/wikidom/lib/es/es.ListBlock.js |
— | — | @@ -97,11 +97,28 @@ |
98 | 98 | position.top += contentOffset.top - blockOffset.top; |
99 | 99 | position.left += contentOffset.left - blockOffset.left; |
100 | 100 | position.bottom += contentOffset.top - blockOffset.top; |
101 | | - position.line += location.linesBefore; |
102 | | - |
| 101 | + |
103 | 102 | return position; |
104 | 103 | }; |
105 | 104 | |
| 105 | +es.ListBlock.prototype.getLineIndex = function( offset ) { |
| 106 | + var globalOffset = 0, |
| 107 | + lineIndex = 0, |
| 108 | + itemLength; |
| 109 | + |
| 110 | + this.list.traverseItems( function( item, index ) { |
| 111 | + itemLength = item.content.getLength(); |
| 112 | + if ( offset >= globalOffset && offset <= globalOffset + itemLength ) { |
| 113 | + lineIndex += item.flow.getLineIndex( offset - globalOffset ); |
| 114 | + return false; |
| 115 | + } |
| 116 | + globalOffset += itemLength + 1; |
| 117 | + lineIndex += item.flow.lines.length; |
| 118 | + } ); |
| 119 | + |
| 120 | + return lineIndex; |
| 121 | +}; |
| 122 | + |
106 | 123 | es.ListBlock.prototype.getText = function( range, render ) { |
107 | 124 | return ""; |
108 | 125 | }; |
Index: trunk/parsers/wikidom/lib/es/es.Surface.js |
— | — | @@ -452,13 +452,16 @@ |
453 | 453 | }; |
454 | 454 | if ( from.location.block === to.location.block ) { |
455 | 455 | var block = from.location.block, |
456 | | - blockOffset = block.$.offset(); |
| 456 | + blockOffset = block.$.offset(), |
| 457 | + fromLineIndex = from.location.block.getLineIndex( this.selection.start.offset ), |
| 458 | + toLineIndex = to.location.block.getLineIndex( this.selection.end.offset ); |
| 459 | + |
457 | 460 | if ( from.location.offset === to.location.offset ) { |
458 | 461 | // No selection, just hide them all |
459 | 462 | this.$rangeStart.hide(); |
460 | 463 | this.$rangeFill.hide(); |
461 | 464 | this.$rangeEnd.hide(); |
462 | | - } else if ( from.position.line === to.position.line ) { |
| 465 | + } else if ( fromLineIndex === toLineIndex ) { |
463 | 466 | // Single line selection |
464 | 467 | this.$rangeStart |
465 | 468 | .css( { |
— | — | @@ -489,7 +492,7 @@ |
490 | 493 | 'height': to.position.bottom - to.position.top |
491 | 494 | } ) |
492 | 495 | .show(); |
493 | | - if ( from.position.line + 1 < to.position.line ) { |
| 496 | + if ( fromLineIndex + 1 < toLineIndex ) { |
494 | 497 | this.$rangeFill |
495 | 498 | .css( { |
496 | 499 | 'top': blockOffset.top + from.position.bottom, |
Index: trunk/parsers/wikidom/lib/es/es.Block.js |
— | — | @@ -192,6 +192,10 @@ |
193 | 193 | throw 'Block.getPosition not implemented in this subclass.'; |
194 | 194 | }; |
195 | 195 | |
| 196 | +es.Block.prototype.getLineIndex = function( offset ) { |
| 197 | + throw 'Block.getLineIndex not implemented in this subclass.'; |
| 198 | +}; |
| 199 | + |
196 | 200 | /** |
197 | 201 | * Gets the start and end points of the word closest a given offset. |
198 | 202 | * |
Index: trunk/parsers/wikidom/lib/es/es.Flow.js |
— | — | @@ -50,6 +50,14 @@ |
51 | 51 | this.scanBoundaries(); |
52 | 52 | } |
53 | 53 | |
| 54 | +es.Flow.prototype.getLineIndex = function( offset ) { |
| 55 | + for ( var i = 0; i < this.lines.length; i++ ) { |
| 56 | + if ( this.lines[i].range.containsOffset( offset ) ) { |
| 57 | + return i; |
| 58 | + } |
| 59 | + } |
| 60 | +}; |
| 61 | + |
54 | 62 | /** |
55 | 63 | * Gets offset within content closest to of a given position. |
56 | 64 | * |
— | — | @@ -74,14 +82,21 @@ |
75 | 83 | return 0; |
76 | 84 | } |
77 | 85 | // Find which line the position is inside of |
78 | | - var lineIndex = this.getLineIndexFromPosition( position ); |
79 | | - |
| 86 | + var i = 0, |
| 87 | + top = 0; |
| 88 | + while ( i < lineCount ) { |
| 89 | + top += this.lines[i].height; |
| 90 | + if ( position.top <= top ) { |
| 91 | + break; |
| 92 | + } |
| 93 | + i++; |
| 94 | + } |
80 | 95 | // Positions below the last line always jump to the last offset |
81 | | - if ( lineIndex == lineCount ) { |
| 96 | + if ( i == lineCount ) { |
82 | 97 | return this.content.getLength(); |
83 | 98 | } |
84 | 99 | // Alias current line object |
85 | | - var line = this.lines[lineIndex]; |
| 100 | + var line = this.lines[i]; |
86 | 101 | |
87 | 102 | /* |
88 | 103 | * Offset finding |
— | — | @@ -112,23 +127,6 @@ |
113 | 128 | }; |
114 | 129 | |
115 | 130 | /** |
116 | | - * Gets a line index for a given position. |
117 | | - * |
118 | | - * @param position {Object} Position to find line index for |
119 | | - * @return {Integer} Line index |
120 | | - */ |
121 | | -es.Flow.prototype.getLineIndexFromPosition = function( position ) { |
122 | | - var i, top = 0; |
123 | | - for ( i = 0; i < this.lines.length; i++ ) { |
124 | | - top += this.lines[i].height; |
125 | | - if ( position.top <= top ) { |
126 | | - break; |
127 | | - } |
128 | | - } |
129 | | - return i; |
130 | | -}; |
131 | | - |
132 | | -/** |
133 | 131 | * Gets position coordinates of a given offset. |
134 | 132 | * |
135 | 133 | * Offsets are boundaries between plain or annotated characters within content. Results are given in |
— | — | @@ -161,20 +159,20 @@ |
162 | 160 | */ |
163 | 161 | var line, |
164 | 162 | lineCount = this.lines.length, |
| 163 | + lineIndex = 0, |
165 | 164 | position = { |
166 | 165 | 'left': 0, |
167 | 166 | 'top': 0, |
168 | | - 'bottom': 0, |
169 | | - 'line': 0 |
| 167 | + 'bottom': 0 |
170 | 168 | }; |
171 | | - while ( position.line < lineCount ) { |
172 | | - line = this.lines[position.line]; |
| 169 | + while ( lineIndex < lineCount ) { |
| 170 | + line = this.lines[lineIndex]; |
173 | 171 | if ( line.range.containsOffset( offset ) ) { |
174 | 172 | position.bottom = position.top + line.height; |
175 | 173 | break; |
176 | 174 | } |
177 | 175 | position.top += line.height; |
178 | | - position.line++; |
| 176 | + lineIndex++; |
179 | 177 | } |
180 | 178 | |
181 | 179 | /* |
— | — | @@ -184,8 +182,7 @@ |
185 | 183 | * line, a virtual n+1 position is supported. Offsets beyond this virtual position will cause |
186 | 184 | * an exception to be thrown. |
187 | 185 | */ |
188 | | - if ( position.line === lineCount ) { |
189 | | - position.line--; |
| 186 | + if ( lineIndex === lineCount ) { |
190 | 187 | position.bottom = position.top; |
191 | 188 | position.top -= line.height; |
192 | 189 | } |
— | — | @@ -560,4 +557,4 @@ |
561 | 558 | return { 'end': start, 'width': lineWidth }; |
562 | 559 | }; |
563 | 560 | |
564 | | -es.extend( es.Flow, es.EventEmitter ); |
| 561 | +es.extend( es.Flow, es.EventEmitter ); |
\ No newline at end of file |