Index: trunk/parsers/wikidom/lib/es/es.Surface.css |
— | — | @@ -30,6 +30,17 @@ |
31 | 31 | position: relative; |
32 | 32 | } |
33 | 33 | |
| 34 | +.editSurface-list { |
| 35 | + margin-left: 1.5em; |
| 36 | +} |
| 37 | + |
| 38 | +.editSurface-list-line { |
| 39 | + padding-left: 1em; |
| 40 | + background-image: url(../../demos/es/images/bullet.png); |
| 41 | + background-position: left center; |
| 42 | + background-repeat: no-repeat; |
| 43 | +} |
| 44 | + |
34 | 45 | .editSurface-line, |
35 | 46 | .editSurface-ruler { |
36 | 47 | line-height: 1.5em; |
Index: trunk/parsers/wikidom/lib/es/es.ListBlock.js |
— | — | @@ -1,25 +1,87 @@ |
2 | | -es.List = function( style, items ) {
|
3 | | - this.style = style;
|
4 | | - this.listItems = [];
|
5 | | -
|
| 2 | +es.ListBlockList = function( style, items ) {
|
| 3 | + // Convert items to es.ListBlockItem objects
|
| 4 | + var listItems = [];
|
6 | 5 | for ( var i = 0; i < items.length; i++ ) {
|
7 | | - this.listItems.push( new es.ListItem( items[i].line, items[i].lists || [] ) );
|
| 6 | + listItems.push( new es.ListBlockItem( items[i].line, items[i].lists || [] ) );
|
8 | 7 | }
|
| 8 | + /*
|
| 9 | + * Initialize container
|
| 10 | + *
|
| 11 | + * - Adds class to container: "editSurface-list"
|
| 12 | + * - Sets .data( 'list', this )
|
| 13 | + * - Adds this.items array
|
| 14 | + */
|
| 15 | + es.Container.call( this, 'list', 'items', listItems );
|
| 16 | +
|
| 17 | + this.style = style;
|
9 | 18 | }
|
10 | 19 |
|
11 | | -es.ListItem = function( line, lists ) {
|
12 | | - this.line = line;
|
13 | | - this.lists = [];
|
| 20 | +/**
|
| 21 | + * Renders content into a container.
|
| 22 | + */
|
| 23 | +es.ListBlockList.prototype.renderContent = function( offset ) {
|
| 24 | + // TODO: Abstract offset and use it when rendering
|
| 25 | + for ( var i = 0; i < this.items.length; i++ ) {
|
| 26 | + this.items[i].renderContent();
|
| 27 | + }
|
| 28 | +};
|
14 | 29 |
|
| 30 | +es.extend( es.ListBlockList, es.Container );
|
| 31 | +
|
| 32 | +es.ListBlockItem = function( line, lists ) {
|
| 33 | + // Convert items to es.ListBlockItem objects
|
| 34 | + var itemLists = [];
|
15 | 35 | for ( var i = 0; i < lists.length; i++ ) {
|
16 | | - this.lists.push( new es.List( lists[i].style, lists[i].items ));
|
| 36 | + itemLists.push( new es.ListBlockList( lists[i].style, lists[i].items || [] ) );
|
17 | 37 | }
|
| 38 | + /*
|
| 39 | + * Initialize container
|
| 40 | + *
|
| 41 | + * - Adds class to container: "editSurface-item"
|
| 42 | + * - Sets .data( 'item', this )
|
| 43 | + * - Adds this.lists array
|
| 44 | + */
|
| 45 | + es.Container.call( this, 'item', 'lists', itemLists );
|
| 46 | +
|
| 47 | + this.$line = $( '<div class="editSurface-list-line"></div>' ).prependTo( this.$ );
|
| 48 | +
|
| 49 | + this.content = line ? es.Content.newFromLine( line ) : new es.Content();
|
| 50 | + this.flow = new es.TextFlow( this.$line, this.content );
|
| 51 | + var item = this;
|
| 52 | + this.flow.on( 'render', function() {
|
| 53 | + item.emit( 'update' );
|
| 54 | + } );
|
18 | 55 | }
|
19 | 56 |
|
| 57 | +es.ListBlockItem.prototype.renderContent = function( offset ) {
|
| 58 | + // TODO: Abstract offset and use it when rendering
|
| 59 | + this.flow.render();
|
| 60 | + for ( var i = 0; i < this.lists.length; i++ ) {
|
| 61 | + this.lists[i].renderContent();
|
| 62 | + }
|
| 63 | +};
|
| 64 | +
|
| 65 | +es.extend( es.ListBlockItem, es.Container );
|
| 66 | +
|
20 | 67 | es.ListBlock = function( style, items ) {
|
21 | | -// var list = new es.List( style, items );
|
| 68 | + es.Block.call( this );
|
| 69 | + this.list = new es.ListBlockList( style, items );
|
| 70 | + this.$ = this.list.$
|
| 71 | + .addClass( 'editSurface-block' )
|
| 72 | + .data( 'block', this );
|
22 | 73 | }
|
23 | 74 |
|
| 75 | +es.ListBlock.newFromWikidom = function( wikidomList ) {
|
| 76 | + return new es.ListBlock( wikidomList.style, wikidomList.items );
|
| 77 | +};
|
| 78 | +
|
| 79 | +/**
|
| 80 | + * Renders content into a container.
|
| 81 | + */
|
| 82 | +es.ListBlock.prototype.renderContent = function( offset ) {
|
| 83 | + this.list.renderContent( offset );
|
| 84 | +};
|
| 85 | +
|
24 | 86 | es.Block.models['list'] = es.ListBlock;
|
25 | 87 |
|
26 | 88 | es.extend( es.ListBlock, es.Block );
|
Index: trunk/parsers/wikidom/lib/es/es.Content.js |
— | — | @@ -143,6 +143,14 @@ |
144 | 144 | } |
145 | 145 | // Apply annotation to range |
146 | 146 | var k; |
| 147 | + if ( src.range.start < 0 ) { |
| 148 | + // TODO: This is invalid data! Throw error? |
| 149 | + src.range.start = 0; |
| 150 | + } |
| 151 | + if ( src.range.end > data.length ) { |
| 152 | + // TODO: This is invalid data! Throw error? |
| 153 | + src.range.end = data.length; |
| 154 | + } |
147 | 155 | for ( k = src.range.start; k < src.range.end; k++ ) { |
148 | 156 | // Auto-convert to array |
149 | 157 | typeof data[k] === 'string' && ( data[k] = [data[k]] ); |
Index: trunk/parsers/wikidom/demos/es/images/bullet.png |
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes on: trunk/parsers/wikidom/demos/es/images/bullet.png |
___________________________________________________________________ |
Added: svn:mime-type |
150 | 158 | + application/octet-stream |
Index: trunk/parsers/wikidom/demos/es/index.html |
— | — | @@ -61,6 +61,7 @@ |
62 | 62 | <script type="text/javascript" src="../../lib/es/es.Surface.js"></script> |
63 | 63 | <script type="text/javascript" src="../../lib/es/es.TextFlow.js"></script> |
64 | 64 | <script type="text/javascript" src="../../lib/es/es.ParagraphBlock.js"></script> |
| 65 | + <script type="text/javascript" src="../../lib/es/es.ListBlock.js"></script> |
65 | 66 | <script type="text/javascript" src="../../lib/es/es.Cursor.js"></script> |
66 | 67 | |
67 | 68 | <!-- Demo --> |
— | — | @@ -103,15 +104,78 @@ |
104 | 105 | ] |
105 | 106 | }, |
106 | 107 | { |
107 | | - "type": "paragraph", |
108 | | - "lines": [ |
109 | | - { 'text': "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." }, |
110 | | - { 'text': "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." }, |
111 | | - { 'text': "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." }, |
112 | | - { 'text': "OccasionallyThereAreWordsThatAreSoLongTheyExceedTheWidthOfTheLineAndEndUpWrappingBetweenMultipleLines." }, |
113 | | - { 'text': "Text might have\ttabs\tin it too. Not all text will end in a line breaking character" } |
| 108 | + 'type': 'list', |
| 109 | + 'style': 'number', |
| 110 | + 'items': [ |
| 111 | + { |
| 112 | + 'line': { 'text': 'First item' }, |
| 113 | + 'lists': [ |
| 114 | + { |
| 115 | + 'type': 'list', |
| 116 | + 'style': 'bullet', |
| 117 | + 'items': [ |
| 118 | + { 'line': { 'text': 'First sub-item' } }, |
| 119 | + { 'line': { 'text': 'Second sub-item' } }, |
| 120 | + { 'line': { 'text': 'Third sub-item' } } |
| 121 | + ] |
| 122 | + } |
| 123 | + ] |
| 124 | + }, |
| 125 | + { |
| 126 | + 'line': { |
| 127 | + 'text': 'Second item', |
| 128 | + 'annotations': [ |
| 129 | + { |
| 130 | + 'type': 'italic', |
| 131 | + 'range': { |
| 132 | + 'start': 0, |
| 133 | + 'end': 6 |
| 134 | + } |
| 135 | + } |
| 136 | + ] |
| 137 | + } |
| 138 | + }, |
| 139 | + { |
| 140 | + 'line': { |
| 141 | + 'text': 'Third item', |
| 142 | + 'annotations': [ |
| 143 | + { |
| 144 | + 'type': 'bold', |
| 145 | + 'range': { |
| 146 | + 'start': 0, |
| 147 | + 'end': 5 |
| 148 | + } |
| 149 | + } |
| 150 | + ] |
| 151 | + } |
| 152 | + }, |
| 153 | + { |
| 154 | + 'line': { |
| 155 | + 'text': 'Fourth item', |
| 156 | + 'annotations': [ |
| 157 | + { |
| 158 | + 'type': 'link', |
| 159 | + 'range': { |
| 160 | + 'start': 7, |
| 161 | + 'end': 11 |
| 162 | + }, |
| 163 | + 'data': { 'title': 'User:JohnDoe' } |
| 164 | + } |
| 165 | + ] |
| 166 | + } |
| 167 | + } |
114 | 168 | ] |
115 | | - } |
| 169 | + }, |
| 170 | + { |
| 171 | + 'type': 'paragraph', |
| 172 | + 'lines': [ |
| 173 | + { 'text': '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.' }, |
| 174 | + { 'text': '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.' }, |
| 175 | + { 'text': '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.' }, |
| 176 | + { 'text': 'OccasionallyThereAreWordsThatAreSoLongTheyExceedTheWidthOfTheLineAndEndUpWrappingBetweenMultipleLines.' }, |
| 177 | + { 'text': 'Text might have\ttabs\tin it too. Not all text will end in a line breaking character' } |
| 178 | + ] |
| 179 | + } |
116 | 180 | ]); |
117 | 181 | var surface = new es.Surface( $('#es-editor'), doc ); |
118 | 182 | |