r89735 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r89734‎ | r89735 | r89736 >
Date:19:11, 8 June 2011
Author:tparscal
Status:deferred
Tags:
Comment:
Integrated neilk's new text-wrap alogorithm, which is much more accurate than the previous version.
Modified paths:
  • /trunk/parsers/wikidom/demos/surface/index.html (modified) (history)
  • /trunk/parsers/wikidom/lib/jquery.editSurface.css (modified) (history)
  • /trunk/parsers/wikidom/lib/jquery.editSurface.js (modified) (history)
  • /trunk/parsers/wikidom/lib/jquery.flow.js (modified) (history)

Diff [purge]

Index: trunk/parsers/wikidom/lib/jquery.flow.js
@@ -5,87 +5,86 @@
66 $.flow = { 'widthCache': {} };
77
88 $.fn.flow = function( text ) {
9 - var lineLimit = $(this).innerWidth();
109
11 - // Wordify
12 - var words = [],
13 - word = { 'text': '', 'width': 0, 'metrics': [] };
14 - for ( var i = 0; i < text.length; i++ ) {
15 - var char = text[i];
16 - // Boundary detection
17 - var boundary = String( ' -\t\r\n\f' ).indexOf( char ) >= 0;
18 - // Encoding
19 - var charHtml = char
20 - .replace( '&', '&amp;' )
 10+ function encodeHtml( c ) {
 11+ return c.replace( '&', '&amp;' )
2112 .replace( ' ', '&nbsp;' )
2213 .replace( '<', '&lt;' )
2314 .replace( '>', '&gt;' )
2415 .replace( '\'', '&apos;' )
2516 .replace( '"', '&quot;' );
26 - // Measurement
27 - var charWidth;
28 - if ( typeof $.flow.widthCache[char] === 'undefined' ) {
29 - charWidth = $.flow.widthCache[char] =
30 - $( '<span>' + charHtml + '</span>' ).appendTo( $(this) ).width();
31 - } else {
32 - charWidth = $.flow.widthCache[char];
33 - }
34 - // Virtual boundary
35 - if ( word.width + charWidth >= lineLimit ) {
36 - words[words.length] = word;
37 - word = { 'text': '', 'width': 0, 'metrics': [] };
38 - }
39 - // Append
40 - if ( boundary ) {
41 - if ( word.text.length ) {
42 - words[words.length] = word;
43 - word = { 'text': '', 'width': 0, 'metrics': [] };
44 - }
45 - words[words.length] = { 'text': char, 'width': charWidth, 'metrics': [charWidth] };
46 - } else {
47 - word.text += char;
48 - word.width += charWidth;
49 - word.metrics[word.metrics.length] = charWidth;
50 - }
5117 }
52 - if ( word.text.length ) {
53 - words[words.length] = word;
54 - }
5518
56 - // Lineify
57 - var lines = [],
58 - line = { 'text': '', 'width': 0, 'metrics': [] };
59 - for ( var i = 0; i < words.length; i++ ) {
60 - var hardReturn = String( '\r\n\f' ).indexOf( words[i].text ) >= 0;
61 - if ( line.width + words[i].width > lineLimit || hardReturn ) {
62 - lines[lines.length] = line;
63 - line = { 'text': '', 'width': 0, 'metrics': [] };
 19+ var breakableRe = /[\s\r\n\f]/;
 20+
 21+ var $this = $(this);
 22+
 23+ $this.empty();
 24+
 25+ var width = $this.innerWidth();
 26+ var pos = 0;
 27+ var line = 0;
 28+
 29+ while( pos < text.length ) {
 30+ var lineStartPos = pos;
 31+ var breakPos = pos;
 32+
 33+ var $line = $( '<div class="editSurface-line"></div>' ).appendTo( $this );
 34+ var lineText = '';
 35+ var lineMetrics = [];
 36+ var lineWidth = 0;
 37+ var lastLineWidth = 0;
 38+
 39+ while ( pos < text.length && lineWidth < width ) {
 40+ // Append text
 41+ lineText += text.charAt( pos );
 42+ // Apply to DOM
 43+ $line.html( encodeHtml( lineText ) );
 44+ // Get new line width from DOM
 45+ lastLineWidth = lineWidth;
 46+ lineWidth = $line.innerWidth();
 47+ // Push difference (character width)
 48+ lineMetrics.push( lineWidth - lastLineWidth );
 49+ if ( breakableRe( text.charAt(pos) ) ) {
 50+ breakPos = pos;
 51+ }
 52+ pos++;
6453 }
65 - if ( !hardReturn && ( line.width > 0 || words[i].text !== ' ' ) ) {
66 - line.text += words[i].text;
67 - line.width += words[i].width;
68 - line.metrics = line.metrics.concat( words[i].metrics );
 54+
 55+ if ( lineWidth >= width ) {
 56+ if ( breakPos === lineStartPos ) {
 57+ // There was no breakable position between the start of the line and here, so we
 58+ // have some kind of long word. Or, the line width is very small. Break at the
 59+ // previous character.
 60+ pos -= 1;
 61+ breakPos = pos;
 62+ } else {
 63+ // Include the breaking character in the previous line
 64+ // TODO: How does this work with hyphens? Won't they be to far right?
 65+ breakPos++;
 66+ }
 67+ lineText = text.substring( lineStartPos, breakPos );
 68+ $line.html( encodeHtml( lineText ) );
 69+ pos = breakPos;
6970 }
70 - }
71 - if ( line.text.length ) {
72 - lines[lines.length] = line;
73 - }
74 -
75 - // Flow
76 - $(this).empty();
77 - for ( var i = 0; i < lines.length; i++ ) {
78 - var $line = $( '<div class="editSurface-line"></div>' )
79 - .data( 'metrics', lines[i].metrics )
80 - .data( 'text', lines[i].text )
81 - .data( 'line', i );
82 - if ( lines[i].text.length ) {
83 - $line.text( lines[i].text );
84 - } else {
85 - $line.html( '&nbsp;' );
86 - $line.addClass( 'empty' );
 71+
 72+ $line
 73+ .data( 'metrics', lineMetrics )
 74+ .data( 'text', lineText )
 75+ .data( 'line', line );
 76+
 77+ if ( lineStartPos === pos ) {
 78+ $line.html( '&nbsp;' )
8779 }
88 - $(this).append( $line );
 80+
 81+ line++;
8982 }
 83+
 84+ return $this;
9085
91 - return $(this);
92 -};
\ No newline at end of file
 86+ // the end
 87+
 88+
 89+
 90+};
 91+
Index: trunk/parsers/wikidom/lib/jquery.editSurface.css
@@ -5,8 +5,8 @@
66
77 #selection {
88 position: absolute;
9 - right: 3%;
10 - width: 45%;
 9+ left: 26em;
 10+ width: 20em;
1111 border: solid 1px Highlight;
1212 line-height: 1.5em;
1313 cursor: text;
@@ -14,27 +14,27 @@
1515
1616 #selection p {
1717 margin: 0;
18 - padding: 1em;
 18+ padding: 0em;
1919 }
2020
2121 .editSurface-container {
2222 position: absolute;
23 - left: 3%;
24 - width: 45%;
 23+ left: 1em;
 24+ width: 24em;
2525 border: solid 1px red;
2626 cursor: text;
2727 }
2828
2929 .editSurface-paragraph {
30 - padding: 1em;
 30+ padding: 0em;
3131 }
3232
33 -.editSurface-container .editSurface-line {
 33+.editSurface-line {
 34+ display: inline-block;
3435 height: 1.5em;
3536 line-height: 1.5em;
36 - width: 100%;
3737 cursor: text;
38 - overflow: hidden;
 38+ white-space: nowrap;
3939 }
4040
4141 .editSurface-range {
Index: trunk/parsers/wikidom/lib/jquery.editSurface.js
@@ -16,7 +16,9 @@
1717 .after( '<div class="editSurface-cursor"></div>' )
1818 .before( '<div class="editSurface-range"></div>'
1919 + '<div class="editSurface-range"></div>'
20 - + '<div class="editSurface-range"></div>')
 20+ + '<div class="editSurface-range"></div>');
 21+
 22+ $(document)
2123 .mousedown( function( e ) {
2224 var $target = $( e.target );
2325 // TODO: If the target is not a line, find the nearest line to the cursor and use it
@@ -44,8 +46,8 @@
4547 } )
4648 .mouseup( function( e ) {
4749 var $target = $( e.target );
48 - if ( !$target.is( '.editSurface-line' ) || !sel.from || !sel.to
49 - || ( sel.from.line === sel.to.line && sel.from.index === sel.to.index ) ) {
 50+ if ( $target.is( '.editSurface-line' ) && ( !sel.from || !sel.to
 51+ || ( sel.from.line === sel.to.line && sel.from.index === sel.to.index ) ) ) {
5052 sel.from = null;
5153 sel.to = null;
5254 sel.start = null;
@@ -74,6 +76,7 @@
7577 }
7678 } );
7779
 80+
7881 // Shortcuts
7982 var $document = $this.find( '.editSurface-document' );
8083 var ranges = {
Index: trunk/parsers/wikidom/demos/surface/index.html
@@ -17,23 +17,25 @@
1818
1919 <!-- Demo -->
2020 <script>
21 - var text = [
22 - "In text display, line wrap is the feature of continuing on a new line when a line is full, such that each line fits in the viewable window, allowing text to be read from top to bottom without any horizontal scrolling.",
23 - "Word wrap is the additional feature of most text editors, word processors, and web browsers, of breaking lines between and not within words, except when a single word is longer than a line.",
24 - "It is usually done on the fly when viewing or printing a document, so no line break code is manually entered, or stored.[citation needed] If the user changes the margins, the editor will either automatically reposition the line breaks to ensure that all the text will \"flow\" within the margins and remain visible, or provide the typist some convenient way to reposition the line breaks.",
25 - "A soft return is the break resulting from line wrap or word wrap, whereas a hard return is an intentional break, creating a new paragraph.",
26 - "The soft returns are usually placed after the ends of complete words, or after the punctuation that follows complete words. However, word wrap may also occur following a hyphen.",
27 - "Word wrap following hyphens is sometimes not desired, and can be avoided by using a so-called non-breaking hyphen instead of a regular hyphen. On the other hand, when using word processors, invisible hyphens, called soft hyphens, can also be inserted inside words so that word wrap can occur following the soft hyphens.",
28 - "Sometimes, word wrap is not desirable between words. In such cases, word wrap can usually be avoided by using a hard space or non-breaking space between the words, instead of regular spaces.",
29 - "OccasionallyThereAreWordsThatAreSoLongTheyExceedTheWidthOfTheLineAndEndUpWrappingBetweenMultipleLines.",
30 - ].join( ' ' );
31 - $( '#es' ).editSurface( {
32 - 'document': { 'blocks': [ {
33 - 'type': 'paragraph',
34 - 'lines': [
35 - { 'text': text }
36 - ]
37 - } ] }
 21+ $(document).ready( function() {
 22+ var text = [
 23+ "In text display, line wrap is the feature of continuing on a new line when a line is full, such that each line fits in the viewable window, allowing text to be read from top to bottom without any horizontal scrolling.",
 24+ "Word wrap is the additional feature of most text editors, word processors, and web browsers, of breaking lines between and not within words, except when a single word is longer than a line.",
 25+ "It is usually done on the fly when viewing or printing a document, so no line break code is manually entered, or stored.[citation needed] If the user changes the margins, the editor will either automatically reposition the line breaks to ensure that all the text will \"flow\" within the margins and remain visible, or provide the typist some convenient way to reposition the line breaks.",
 26+ "A soft return is the break resulting from line wrap or word wrap, whereas a hard return is an intentional break, creating a new paragraph.",
 27+ "The soft returns are usually placed after the ends of complete words, or after the punctuation that follows complete words. However, word wrap may also occur following a hyphen.",
 28+ "Word wrap following hyphens is sometimes not desired, and can be avoided by using a so-called non-breaking hyphen instead of a regular hyphen. On the other hand, when using word processors, invisible hyphens, called soft hyphens, can also be inserted inside words so that word wrap can occur following the soft hyphens.",
 29+ "Sometimes, word wrap is not desirable between words. In such cases, word wrap can usually be avoided by using a hard space or non-breaking space between the words, instead of regular spaces.",
 30+ "OccasionallyThereAreWordsThatAreSoLongTheyExceedTheWidthOfTheLineAndEndUpWrappingBetweenMultipleLines.",
 31+ ].join( ' ' );
 32+ $( '#es' ).editSurface( {
 33+ 'document': { 'blocks': [ {
 34+ 'type': 'paragraph',
 35+ 'lines': [
 36+ { 'text': text }
 37+ ]
 38+ } ] }
 39+ } );
3840 } );
3941 </script>
4042 </body>

Status & tagging log