Index: trunk/extensions/VisualEditor/tests/parser/parserTests.js |
— | — | @@ -307,6 +307,10 @@ |
308 | 308 | .replace(/(title|class|rel)="[^"]+"/g, '') |
309 | 309 | // strip red link markup, we do not check if a page exists yet |
310 | 310 | .replace(/\/index.php\?title=|&action=edit&redlink=1/g, '') |
| 311 | + // do not expect a toc for now |
| 312 | + .replace(/<table id="toc>.*?<\/table>/g, '') |
| 313 | + // do not expect section editing for now |
| 314 | + .replace(/<h[1-6]> <span>[.*?<\/span><span.*?]<\/span>/g, '') |
311 | 315 | // the expected html has some extra space in tags, strip it |
312 | 316 | .replace(/<a +href/g, '<a href') |
313 | 317 | .replace(/" +>/g, '">'); |
Index: trunk/extensions/VisualEditor/modules/parser/pegParser.pegjs.txt |
— | — | @@ -356,7 +356,25 @@ |
357 | 357 | // text start position |
358 | 358 | var textStart = 0; |
359 | 359 | |
| 360 | + // hack to support numbered external links ([http://example.com]). |
| 361 | + // XXX: Move to token stream transform after templates are expanded! |
360 | 362 | var linkCount = 1; |
| 363 | + |
| 364 | + // Define block-level tags in JS, so we can use toLowerCase to match tags |
| 365 | + // case-independently. This would be quite ugly (and possibly slower) if |
| 366 | + // done manually in the grammar. |
| 367 | + var block_names = (function () { |
| 368 | + var names = [ "p", "table", "td", "tr", "ul", "ol" |
| 369 | + , "li", "dl", "dt", "dd", "div", "center" |
| 370 | + , "blockquote" ]; |
| 371 | + var bnames = {}; |
| 372 | + for(var i = 0, l = names.length; i < l; i++) { |
| 373 | + bnames[names[i]] = true; |
| 374 | + } |
| 375 | + return bnames; |
| 376 | + })(); |
| 377 | + |
| 378 | + |
361 | 379 | } |
362 | 380 | |
363 | 381 | start |
— | — | @@ -920,10 +938,14 @@ |
921 | 939 | // See http://dev.w3.org/html5/spec/Overview.html#syntax-tag-name and |
922 | 940 | // following paragraphs |
923 | 941 | block_tag |
924 | | - = "<" end:"/"? name:block_name |
| 942 | + = "<" end:"/"? name:(cs:[a-zA-Z]+ { return cs.join('') }) |
925 | 943 | attribs:generic_attribute* |
926 | 944 | selfclose:"/"? |
927 | 945 | ">" { |
| 946 | + if (block_names[name.toLowerCase()] !== true) { |
| 947 | + // abort match if tag is not block-level |
| 948 | + return null; |
| 949 | + } |
928 | 950 | var res = {name: name, attribs: attribs}; |
929 | 951 | if ( end != '' ) { |
930 | 952 | res.type = 'ENDTAG'; |
— | — | @@ -935,12 +957,7 @@ |
936 | 958 | return res; |
937 | 959 | } |
938 | 960 | |
939 | | -block_name |
940 | | - = "p" / "table" / "td" / "tr" / "ul" / "ol" |
941 | | - / "li" / "dl" / "dt" / "dd" / "div" / "center" |
942 | | - / "blockquote" |
943 | 961 | |
944 | | - |
945 | 962 | // See http://dev.w3.org/html5/spec/Overview.html#syntax-tag-name and |
946 | 963 | // following paragraphs |
947 | 964 | generic_tag |
— | — | @@ -1101,9 +1118,11 @@ |
1102 | 1119 | } |
1103 | 1120 | |
1104 | 1121 | li = bullets:list_char+ |
1105 | | - c:inlineline |
| 1122 | + c:inlineline? |
1106 | 1123 | &eolf |
1107 | 1124 | { |
| 1125 | + if ( c == '' ) |
| 1126 | + c = []; |
1108 | 1127 | return [ { type: 'TAG', |
1109 | 1128 | name: 'listItem', |
1110 | 1129 | bullets: bullets } |