Index: trunk/extensions/VisualEditor/tests/parser/parserTests-whitelist.js |
— | — | @@ -20,7 +20,11 @@ |
21 | 21 | // This is a rare edge case, and the new behavior is arguably more consistent |
22 | 22 | testWhiteList["5 quotes, code coverage +1 line"] = "<p>'<i></i></p>"; |
23 | 23 | |
| 24 | +// The comment in the test already suggests this result as correct, but |
| 25 | +// supplies the old result without preformatting. |
| 26 | +testWhiteList["Bug 6200: Preformatted in <blockquote>"] = "<blockquote data-sourcePos=\"0:12\"><pre>\nBlah</pre></blockquote>"; |
24 | 27 | |
| 28 | + |
25 | 29 | // empty table tags / with only a caption are legal in HTML5. |
26 | 30 | testWhiteList["A table with no data."] = "<table></table>"; |
27 | 31 | testWhiteList["A table with nothing but a caption"] = "<table><caption> caption</caption></table>"; |
Index: trunk/extensions/VisualEditor/modules/parser/ext.core.QuoteTransformer.js |
— | — | @@ -38,8 +38,8 @@ |
39 | 39 | this.quoteAndNewlineRank, 'newline' ); |
40 | 40 | dispatcher.addTransform( this.onQuote.bind(this), |
41 | 41 | this.quoteAndNewlineRank, 'tag', 'mw-quote' ); |
42 | | - // Reset internal state when we are done |
43 | | - dispatcher.addTransform( this.reset.bind(this), |
| 42 | + // Treat end-of-input just the same as a newline |
| 43 | + dispatcher.addTransform( this.onNewLine.bind(this), |
44 | 44 | this.quoteAndNewlineRank, 'end' ); |
45 | 45 | }; |
46 | 46 | |
Index: trunk/extensions/VisualEditor/modules/parser/ext.Util.js |
— | — | @@ -1,5 +1,6 @@ |
2 | 2 | /** |
3 | 3 | * General utilities for token transforms |
| 4 | + * XXX: move this to MWParserEnvironment? |
4 | 5 | */ |
5 | 6 | |
6 | 7 | function Util () { |
Index: trunk/extensions/VisualEditor/modules/parser/pegTokenizer.pegjs.txt |
— | — | @@ -769,7 +769,8 @@ |
770 | 770 | "]]" |
771 | 771 | // XXX In real MediaWiki, this is a language-dependent positive character |
772 | 772 | // class. Can we work out a static negative class instead? |
773 | | - trail:(! [ \t(),.:-] tc:text_char { return tc })* { |
| 773 | + // XXX: Exclude uppercase chars from non-latin languages too! |
| 774 | + trail:(! [A-Z \t(),.:-] tc:text_char { return tc })* { |
774 | 775 | var obj = { |
775 | 776 | type: 'TAG', |
776 | 777 | name: 'a', |
Index: trunk/extensions/VisualEditor/modules/parser/mediawiki.tokenizer.peg.js |
— | — | @@ -49,7 +49,7 @@ |
50 | 50 | out = this.parser.parse(text); |
51 | 51 | // emit tokens here until we get that to work per toplevelblock in the |
52 | 52 | // actual tokenizer |
53 | | - this.emit('chunk', out); |
| 53 | + this.emit('chunk', out.concat( [{ type: 'END' }] ) ); |
54 | 54 | this.emit('end'); |
55 | 55 | //} catch (e) { |
56 | 56 | //err = e; |
Index: trunk/extensions/VisualEditor/modules/parser/ext.core.PostExpandParagraphHandler.js |
— | — | @@ -32,7 +32,7 @@ |
33 | 33 | }; |
34 | 34 | |
35 | 35 | PostExpandParagraphHandler.prototype.reset = function ( token, cb, frame, prevToken ) { |
36 | | - //console.log( 'PostExpandParagraphHandler.reset' ); |
| 36 | + //console.log( 'PostExpandParagraphHandler.reset ' + JSON.stringify( this.tokens ) ); |
37 | 37 | if ( this.newLines ) { |
38 | 38 | return { tokens: this._finish() }; |
39 | 39 | } else { |
Index: trunk/extensions/VisualEditor/modules/parser/ext.core.TemplateHandler.js |
— | — | @@ -18,8 +18,9 @@ |
19 | 19 | this.register( manager ); |
20 | 20 | } |
21 | 21 | |
22 | | -TemplateHandler.prototype.reset = function () { |
| 22 | +TemplateHandler.prototype.reset = function ( token ) { |
23 | 23 | this.resultTokens = []; |
| 24 | + return {token: token}; |
24 | 25 | }; |
25 | 26 | |
26 | 27 | // constants |
— | — | @@ -34,8 +35,8 @@ |
35 | 36 | this.rank, 'tag', 'templatearg' ); |
36 | 37 | |
37 | 38 | // Reset internal state when the parser pipeline is done |
38 | | - manager.addTransform( this.reset.bind(this), |
39 | | - this.rank, 'end' ); |
| 39 | + //manager.addTransform( this.reset.bind(this), |
| 40 | + // this.rank, 'end' ); |
40 | 41 | }; |
41 | 42 | |
42 | 43 | |
— | — | @@ -119,7 +120,20 @@ |
120 | 121 | tokens: [ |
121 | 122 | { |
122 | 123 | type: 'TEXT', |
123 | | - value: 'Template expansion loop detected!' |
| 124 | + value: 'Template loop detected: ' |
| 125 | + }, |
| 126 | + { |
| 127 | + type: 'TAG', |
| 128 | + name: 'a', |
| 129 | + attrib: [['href', target]] |
| 130 | + }, |
| 131 | + { |
| 132 | + type: 'TEXT', |
| 133 | + value: target |
| 134 | + }, |
| 135 | + { |
| 136 | + type: 'ENDTAG', |
| 137 | + name: 'a' |
124 | 138 | } |
125 | 139 | ] |
126 | 140 | }; |
— | — | @@ -186,12 +200,18 @@ |
187 | 201 | }; |
188 | 202 | |
189 | 203 | /** |
190 | | - * Handle the end event by calling our parentCB with notYetDone set to false. |
| 204 | + * Handle the end event emitted by the parser pipeline by calling our parentCB |
| 205 | + * with notYetDone set to false. |
191 | 206 | */ |
192 | | -TemplateHandler.prototype._onEnd = function( ) { |
| 207 | +TemplateHandler.prototype._onEnd = function( token ) { |
193 | 208 | // Encapsulate the template in a single token, which contains all the |
194 | 209 | // information needed for the editor. |
195 | 210 | var res = this.resultTokens; |
| 211 | + // Remove 'end' token from end |
| 212 | + if ( res.length && res[res.length - 1].type === 'END' ) { |
| 213 | + res.pop(); |
| 214 | + } |
| 215 | + |
196 | 216 | /* |
197 | 217 | [{ |
198 | 218 | type: 'TAG', |
— | — | @@ -209,7 +229,6 @@ |
210 | 230 | |
211 | 231 | if ( this.isAsync ) { |
212 | 232 | this.parentCB( res, false ); |
213 | | - this.reset(); |
214 | 233 | } else { |
215 | 234 | this.result = { tokens: res }; |
216 | 235 | this.reset(); |