Index: trunk/extensions/VisualEditor/tests/parser/__patched-html5-parser.js |
— | — | @@ -1,43 +1,38 @@ |
2 | | -module.exports = function (HTML5) { |
3 | | - var htmlparser = new HTML5.Parser(); |
4 | | - htmlparser.tree.elementInActiveFormattingElements = function(name) { |
5 | | - var els = this.activeFormattingElements; |
6 | | - for(var i = els.length - 1; i >= 0; i--) { |
7 | | - if(els[i].type == HTML5.Marker.type) break; |
8 | | - if(els[i].tagName.toLowerCase() == name) return els[i]; |
9 | | - } |
10 | | - return false; |
11 | | - }; |
12 | | - htmlparser.tree.reconstructActiveFormattingElements = function() { |
13 | | - // Within this algorithm the order of steps decribed in the specification |
14 | | - // is not quite the same as the order of steps in the code. It should still |
15 | | - // do the same though. |
16 | 2 | |
17 | | - // Step 1: stop if there's nothing to do |
18 | | - if(this.activeFormattingElements.length == 0) return; |
19 | | - |
20 | | - // Step 2 and 3: start with the last element |
21 | | - var i = this.activeFormattingElements.length - 1; |
22 | | - var entry = this.activeFormattingElements[i]; |
23 | | - if(entry.type == HTML5.Marker.type || this.open_elements.indexOf(entry) != -1) return; |
24 | | - |
25 | | - while(entry.type != HTML5.Marker.type && this.open_elements.indexOf(entry) == -1) { |
26 | | - i -= 1; |
27 | | - entry = this.activeFormattingElements[i]; |
28 | | - if(!entry) break; |
29 | | - } |
30 | | - |
31 | | - while(true) { |
32 | | - i += 1; |
33 | | - var clone = this.activeFormattingElements[i].cloneNode(); |
34 | | - |
35 | | - var element = this.insert_element(clone.tagName, clone.attributes); |
36 | | - |
37 | | - this.activeFormattingElements[i] = element; |
38 | | - |
39 | | - if(element == this.activeFormattingElements.last()) break; |
40 | | - } |
41 | | - }; |
42 | | - |
43 | | - return htmlparser; |
| 3 | +module.exports = function(HTML5) { |
| 4 | + var htmlparser; |
| 5 | + htmlparser = new HTML5.Parser; |
| 6 | + htmlparser.tree.elementInActiveFormattingElements = function(name) { |
| 7 | + var els, i; |
| 8 | + els = this.activeFormattingElements; |
| 9 | + i = els.length - 1; |
| 10 | + while (i >= 0) { |
| 11 | + if (els[i].type === HTML5.Marker.type) break; |
| 12 | + if (els[i].tagName.toLowerCase() === name) return els[i]; |
| 13 | + i--; |
| 14 | + } |
| 15 | + return false; |
| 16 | + }; |
| 17 | + htmlparser.tree.reconstructActiveFormattingElements = function() { |
| 18 | + var clone, element, entry, i; |
| 19 | + if (this.activeFormattingElements.length === 0) return; |
| 20 | + i = this.activeFormattingElements.length - 1; |
| 21 | + entry = this.activeFormattingElements[i]; |
| 22 | + if (entry.type === HTML5.Marker.type || this.open_elements.indexOf(entry) !== -1) { |
| 23 | + return; |
| 24 | + } |
| 25 | + while (entry.type !== HTML5.Marker.type && this.open_elements.indexOf(entry) === -1) { |
| 26 | + i -= 1; |
| 27 | + entry = this.activeFormattingElements[i]; |
| 28 | + if (!entry) break; |
| 29 | + } |
| 30 | + while (true) { |
| 31 | + i += 1; |
| 32 | + clone = this.activeFormattingElements[i].cloneNode(); |
| 33 | + element = this.insert_element(clone.tagName, clone.attributes); |
| 34 | + this.activeFormattingElements[i] = element; |
| 35 | + if (element === this.activeFormattingElements.last()) break; |
| 36 | + } |
| 37 | + }; |
| 38 | + return htmlparser; |
44 | 39 | }; |
Index: trunk/extensions/VisualEditor/tests/parser/Makefile |
— | — | @@ -1,8 +1,17 @@ |
2 | | -test :: parserTests.txt |
| 2 | +COFFEE = $(shell find . -name '*.coffee' -a ! -regex '.*node_modules.*' | sed 's/\.coffee/\.js/') |
| 3 | + |
| 4 | +all :: $(COFFEE) |
| 5 | + |
| 6 | +test :: parserTests.txt all |
3 | 7 | node ./parserTests.js --cache parserTests.txt |
4 | 8 | |
5 | 9 | TESTS_URL = http://svn.wikimedia.org/svnroot/mediawiki/trunk/phase3/tests/parser/parserTests.txt |
6 | 10 | parserTests.txt :: |
7 | 11 | -if [ ! -e parserTests.txt ] ; then curl -O $(TESTS_URL) || wget $(TESTS_URL) ; fi |
8 | 12 | |
9 | | -.PHONY: test |
| 13 | +.PHONY: test all |
| 14 | + |
| 15 | +.SUFFIXES: .coffee .js |
| 16 | + |
| 17 | +.coffee.js: |
| 18 | + coffee -c -b $< |
Index: trunk/extensions/VisualEditor/tests/parser/README |
— | — | @@ -14,6 +14,7 @@ |
15 | 15 | * libxmljs (requires native compilation) |
16 | 16 | * optimist (for argument handling) |
17 | 17 | * webworker (not needed for parserTests) |
| 18 | +* coffee-script (if you'd like to modify .coffee files) |
18 | 19 | |
19 | 20 | == Running parserTests.js == |
20 | 21 | |
— | — | @@ -21,7 +22,8 @@ |
22 | 23 | either in a phase3 checkout parallel to extensions (tried by default). You can |
23 | 24 | also specify a test case file as an argument. |
24 | 25 | |
25 | | -Then, in this directory, try: |
| 26 | +The "make test" target in this directory downloads parserTests.txt and specifies |
| 27 | +it as the test case automatically. Of course, you may also run tests manually: |
26 | 28 | |
27 | 29 | node ./parserTests.js |
28 | 30 | |
Index: trunk/extensions/VisualEditor/tests/parser/__patched-html5-parser.coffee |
— | — | @@ -0,0 +1,30 @@ |
| 2 | +module.exports = (HTML5) -> |
| 3 | + htmlparser = new HTML5.Parser |
| 4 | + |
| 5 | + htmlparser.tree.elementInActiveFormattingElements = (name) -> |
| 6 | + els = @activeFormattingElements |
| 7 | + i = els.length - 1 |
| 8 | + while i >= 0 |
| 9 | + break if els[i].type is HTML5.Marker.type |
| 10 | + return els[i] if els[i].tagName.toLowerCase() is name |
| 11 | + i-- |
| 12 | + return false |
| 13 | + |
| 14 | + htmlparser.tree.reconstructActiveFormattingElements = -> |
| 15 | + return if @activeFormattingElements.length is 0 |
| 16 | + i = @activeFormattingElements.length - 1 |
| 17 | + entry = @activeFormattingElements[i] |
| 18 | + return if entry.type is HTML5.Marker.type or @open_elements.indexOf(entry) isnt -1 |
| 19 | + while entry.type isnt HTML5.Marker.type and @open_elements.indexOf(entry) is -1 |
| 20 | + i -= 1 |
| 21 | + entry = @activeFormattingElements[i] |
| 22 | + break unless entry |
| 23 | + loop |
| 24 | + i += 1 |
| 25 | + clone = @activeFormattingElements[i].cloneNode() |
| 26 | + element = @insert_element(clone.tagName, clone.attributes) |
| 27 | + @activeFormattingElements[i] = element |
| 28 | + break if element is @activeFormattingElements.last() |
| 29 | + return |
| 30 | + |
| 31 | + return htmlparser |