Index: trunk/parsers/wikidom/lib/es/es.TextFlow.js |
— | — | @@ -11,6 +11,7 @@ |
12 | 12 | this.lines = []; |
13 | 13 | this.width = null; |
14 | 14 | this.boundaryTest = /([ \-\t\r\n\f])/g; |
| 15 | + this.widthCache = {}; |
15 | 16 | } |
16 | 17 | |
17 | 18 | /** |
— | — | @@ -20,7 +21,7 @@ |
21 | 22 | * @return {String} HTML escaped text |
22 | 23 | */ |
23 | 24 | TextFlow.prototype.escape = function( start, end ) { |
24 | | - return text |
| 25 | + return this.content.substring( start, end ) |
25 | 26 | // Tags |
26 | 27 | .replace( /&/g, '&' ) |
27 | 28 | .replace( /</g, '<' ) |
— | — | @@ -214,6 +215,8 @@ |
215 | 216 | * @param callback {Function} Function to execute when flowing is complete |
216 | 217 | */ |
217 | 218 | TextFlow.prototype.render = function( offset, callback ) { |
| 219 | + this.widthCache = {}; |
| 220 | + |
218 | 221 | // Reset lines in the DOM and the "lines" array |
219 | 222 | this.$.empty(); |
220 | 223 | |
— | — | @@ -331,14 +334,21 @@ |
332 | 335 | TextFlow.prototype.fitWords = function( start, end, ruler, width ) { |
333 | 336 | var offset = start, |
334 | 337 | middle, |
335 | | - lineWidth; |
| 338 | + lineWidth, |
| 339 | + cacheKey; |
336 | 340 | do { |
337 | 341 | // Place "middle" directly in the center of "start" and "end" |
338 | 342 | middle = Math.ceil( ( start + end ) / 2 ); |
| 343 | + |
| 344 | + cacheKey = this.boundaries[offset] + ':' + this.boundaries[middle]; |
| 345 | + |
339 | 346 | // Prepare the line for measurement using pre-escaped HTML |
340 | 347 | ruler.innerHTML = this.escape( this.boundaries[offset], this.boundaries[middle] ); |
341 | 348 | // Test for over/under using width of the rendered line |
342 | | - if ( ( lineWidth = ruler.clientWidth ) > width ) { |
| 349 | + this.widthCache[cacheKey] = lineWidth = ruler.clientWidth; |
| 350 | + |
| 351 | + // Test for over/under using width of the rendered line |
| 352 | + if ( lineWidth > width ) { |
343 | 353 | // Detect impossible fit (the first word won't fit by itself) |
344 | 354 | if (middle - offset === 1) { |
345 | 355 | start = middle; |
— | — | @@ -370,14 +380,24 @@ |
371 | 381 | TextFlow.prototype.fitCharacters = function( start, end, ruler, width ) { |
372 | 382 | var offset = start, |
373 | 383 | middle, |
374 | | - lineWidth; |
| 384 | + lineWidth, |
| 385 | + cacheKey; |
375 | 386 | do { |
376 | 387 | // Place "middle" directly in the center of "start" and "end" |
377 | 388 | middle = Math.ceil( ( start + end ) / 2 ); |
378 | | - // Fill the line with a portion of the text, escaped as HTML |
379 | | - ruler.innerHTML = this.escape( offset, middle ); |
380 | | - // Test for over/under using width of the rendered line |
381 | | - if ( ( lineWidth = ruler.clientWidth ) > width ) { |
| 389 | + |
| 390 | + cacheKey = offset + ':' + middle; |
| 391 | + |
| 392 | + if ( cacheKey in this.widthCache ) { |
| 393 | + lineWidth = this.widthCache[cacheKey]; |
| 394 | + } else { |
| 395 | + // Fill the line with a portion of the text, escaped as HTML |
| 396 | + ruler.innerHTML = this.escape( offset, middle ); |
| 397 | + // Test for over/under using width of the rendered line |
| 398 | + this.widthCache[cacheKey] = lineWidth = ruler.clientWidth; |
| 399 | + } |
| 400 | + |
| 401 | + if ( lineWidth > width ) { |
382 | 402 | // Detect impossible fit (the first character won't fit by itself) |
383 | 403 | if (middle - offset === 1) { |
384 | 404 | start = middle - 1; |