hatemile 2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/CODE_OF_CONDUCT.md +46 -0
  3. data/Gemfile +9 -0
  4. data/LICENSE +202 -0
  5. data/Rakefile +64 -0
  6. data/hatemile.gemspec +37 -0
  7. data/lib/hatemile/accessible_association.rb +62 -0
  8. data/lib/hatemile/accessible_css.rb +43 -0
  9. data/lib/hatemile/accessible_display.rb +178 -0
  10. data/lib/hatemile/accessible_event.rb +95 -0
  11. data/lib/hatemile/accessible_form.rb +101 -0
  12. data/lib/hatemile/accessible_navigation.rb +82 -0
  13. data/lib/hatemile/helper.rb +58 -0
  14. data/lib/hatemile/implementation/accessible_association_implementation.rb +346 -0
  15. data/lib/hatemile/implementation/accessible_css_implementation.rb +772 -0
  16. data/lib/hatemile/implementation/accessible_display_implementation.rb +1362 -0
  17. data/lib/hatemile/implementation/accessible_event_implementation.rb +278 -0
  18. data/lib/hatemile/implementation/accessible_form_implementation.rb +386 -0
  19. data/lib/hatemile/implementation/accessible_navigation_implementation.rb +561 -0
  20. data/lib/hatemile/util/common_functions.rb +106 -0
  21. data/lib/hatemile/util/configure.rb +92 -0
  22. data/lib/hatemile/util/css/rcp/rcp_declaration.rb +77 -0
  23. data/lib/hatemile/util/css/rcp/rcp_parser.rb +115 -0
  24. data/lib/hatemile/util/css/rcp/rcp_rule.rb +86 -0
  25. data/lib/hatemile/util/css/style_sheet_declaration.rb +59 -0
  26. data/lib/hatemile/util/css/style_sheet_parser.rb +43 -0
  27. data/lib/hatemile/util/css/style_sheet_rule.rb +73 -0
  28. data/lib/hatemile/util/html/html_dom_element.rb +234 -0
  29. data/lib/hatemile/util/html/html_dom_node.rb +131 -0
  30. data/lib/hatemile/util/html/html_dom_parser.rb +150 -0
  31. data/lib/hatemile/util/html/html_dom_text_node.rb +43 -0
  32. data/lib/hatemile/util/html/nokogiri/nokogiri_html_dom_element.rb +302 -0
  33. data/lib/hatemile/util/html/nokogiri/nokogiri_html_dom_node.rb +112 -0
  34. data/lib/hatemile/util/html/nokogiri/nokogiri_html_dom_parser.rb +208 -0
  35. data/lib/hatemile/util/html/nokogiri/nokogiri_html_dom_text_node.rb +83 -0
  36. data/lib/hatemile/util/id_generator.rb +53 -0
  37. data/lib/js/common.js +98 -0
  38. data/lib/js/eventlistener.js +36 -0
  39. data/lib/js/include.js +292 -0
  40. data/lib/js/scriptlist_validation_fields.js +13 -0
  41. data/lib/js/validation.js +205 -0
  42. data/lib/locale/en-US.yml +388 -0
  43. data/lib/locale/pt-BR.yml +389 -0
  44. data/lib/skippers.xml +6 -0
  45. data/lib/symbols.xml +40 -0
  46. data/test/locale/en-US.yml +5 -0
  47. data/test/locale/pt-BR.yml +4 -0
  48. data/test/test_accessible_association_implementation.rb +258 -0
  49. data/test/test_accessible_css_implementation.rb +518 -0
  50. data/test/test_accessible_display_implementation.rb +873 -0
  51. data/test/test_accessible_form_implementation.rb +283 -0
  52. data/test/test_accessible_navigation_implementation.rb +228 -0
  53. data/test/test_common_functions.rb +128 -0
  54. data/test/test_configure.rb +73 -0
  55. data/test/test_nokogiri_html_dom_element.rb +586 -0
  56. data/test/test_nokogiri_html_dom_parser.rb +363 -0
  57. data/test/test_nokogiri_html_dom_text_node.rb +225 -0
  58. data/test/test_rcp_declaration.rb +103 -0
  59. data/test/test_rcp_parser.rb +86 -0
  60. data/test/test_rcp_rule.rb +89 -0
  61. metadata +199 -0
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <skippers>
3
+ <skipper selector="main,[role=main]" description="skipper-main-content" shortcut="1" />
4
+ <skipper selector="#container-shortcuts-after" description="skipper-shortcuts-list" shortcut="9" />
5
+ <skipper selector="#container-heading-after" description="skipper-table-contents" shortcut="0" />
6
+ </skippers>
@@ -0,0 +1,40 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE symbols [
3
+ <!ENTITY quot '"'>
4
+ <!ENTITY amp '&#38;'>
5
+ <!ENTITY lt '<'>
6
+ ]>
7
+ <symbols>
8
+ <symbol symbol="!" description="symbol-exclamation-mark" />
9
+ <symbol symbol="&quot;" description="symbol-double-quotes" />
10
+ <symbol symbol="#" description="symbol-number" />
11
+ <symbol symbol="$" description="symbol-dollar" />
12
+ <symbol symbol="%" description="symbol-percent" />
13
+ <symbol symbol="&amp;" description="symbol-ampersand" />
14
+ <symbol symbol="'" description="symbol-single-quote" />
15
+ <symbol symbol="(" description="symbol-open-parenthesis" />
16
+ <symbol symbol=")" description="symbol-close-parenthesis" />
17
+ <symbol symbol="*" description="symbol-asterisk" />
18
+ <symbol symbol="+" description="symbol-plus" />
19
+ <symbol symbol="," description="symbol-comma" />
20
+ <symbol symbol="-" description="symbol-hyphen" />
21
+ <symbol symbol="." description="symbol-dot" />
22
+ <symbol symbol="/" description="symbol-slash" />
23
+ <symbol symbol=":" description="symbol-colon" />
24
+ <symbol symbol=";" description="symbol-semicolon" />
25
+ <symbol symbol="&lt;" description="symbol-less-than" />
26
+ <symbol symbol="=" description="symbol-equals" />
27
+ <symbol symbol=">" description="symbol-greater-than" />
28
+ <symbol symbol="?" description="symbol-question-mark" />
29
+ <symbol symbol="@" description="symbol-at" />
30
+ <symbol symbol="[" description="symbol-open-bracket" />
31
+ <symbol symbol="\" description="symbol-backslash" />
32
+ <symbol symbol="]" description="symbol-close-bracket" />
33
+ <symbol symbol="^" description="symbol-caret" />
34
+ <symbol symbol="_" description="symbol-underscore" />
35
+ <symbol symbol="`" description="symbol-grave-accent" />
36
+ <symbol symbol="{" description="symbol-open-brace" />
37
+ <symbol symbol="|" description="symbol-vertical-bar" />
38
+ <symbol symbol="}" description="symbol-close-brace" />
39
+ <symbol symbol="~" description="symbol-tilde" />
40
+ </symbols>
@@ -0,0 +1,5 @@
1
+ en-US:
2
+ hatemile:
3
+ text-shortcuts: "Shortcuts:"
4
+ text-standart-shortcut-prefix: "ALT"
5
+ text-heading: "Summary:"
@@ -0,0 +1,4 @@
1
+ pt-BR:
2
+ hatemile:
3
+ text-shortcuts: "Atalhos:"
4
+ text-standart-shortcut-prefix: "ALT"
@@ -0,0 +1,258 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+ require 'test/unit'
16
+ require 'test/unit/assertions'
17
+
18
+ require File.join(
19
+ File.dirname(File.dirname(__FILE__)),
20
+ 'lib',
21
+ 'hatemile',
22
+ 'implementation',
23
+ 'accessible_association_implementation'
24
+ )
25
+ require File.join(
26
+ File.dirname(File.dirname(__FILE__)),
27
+ 'lib',
28
+ 'hatemile',
29
+ 'util',
30
+ 'html',
31
+ 'nokogiri',
32
+ 'nokogiri_html_dom_parser'
33
+ )
34
+
35
+ ##
36
+ # Test methods of Hatemile::Implementation::AccessibleAssociationImplementation
37
+ # class.
38
+ class TestAccessibleAssociationImplementation < Test::Unit::TestCase
39
+ ##
40
+ # The name of attribute for not modify the elements.
41
+ DATA_IGNORE = 'data-ignoreaccessibilityfix="true"'.freeze
42
+
43
+ ##
44
+ # Initialize common attributes used by test methods.
45
+ def setup
46
+ @html_parser = Hatemile::Util::Html::NokogiriLib::NokogiriHTMLDOMParser.new(
47
+ "<!DOCTYPE html>
48
+ <html>
49
+ <head>
50
+ <title>HaTeMiLe Tests</title>
51
+ <meta charset=\"UTF-8\" />
52
+ </head>
53
+ <body>
54
+ <table id=\"table1\">
55
+ <thead>
56
+ <tr>
57
+ <th rowspan=\"2\" data-id=\"t1column11\">Column 1.1</th>
58
+ <th id=\"t1column12\">Column 1.2</th>
59
+ <th id=\"t1column13\" #{DATA_IGNORE}>Column 1.3</th>
60
+ <td id=\"t1column14\">Column 1.4</td>
61
+ </tr>
62
+ <tr>
63
+ <th id=\"t1column22\">Column 2.2</th>
64
+ <th colspan=\"2\" id=\"t1column23\">Column 2.3</th>
65
+ </tr>
66
+ </thead>
67
+ <tbody>
68
+ <tr>
69
+ <th rowspan=\"2\" id=\"t1cell11\">Cell 1.1</th>
70
+ <td id=\"t1cell12\" #{DATA_IGNORE}>Cell 1.2</td>
71
+ <td data-id=\"t1cell13\">Cell 1.3</td>
72
+ <td id=\"t1cell14\">Cell 1.4</td>
73
+ </tr>
74
+ <tr>
75
+ <td colspan=\"3\" id=\"t1cell22\">Cell 2.2</td>
76
+ </tr>
77
+ </tbody>
78
+ </table>
79
+ <table id=\"table2\">
80
+ <thead>
81
+ <tr>
82
+ <th rowspan=\"2\" id=\"t2column11\">Column 1.1</th>
83
+ <th id=\"t2column12\">Column 1.2</th>
84
+ <th id=\"t2column13\">Column 1.3</th>
85
+ </tr>
86
+ <tr>
87
+ <th id=\"t2column22\">Column 2.2</th>
88
+ <th colspan=\"2\" id=\"t2column23\">Column 2.3</th>
89
+ </tr>
90
+ </thead>
91
+ <tbody>
92
+ <tr>
93
+ <td rowspan=\"2\" id=\"t2cell11\">Cell 1.1</th>
94
+ <td id=\"t2cell12\">Cell 1.2</td>
95
+ <td id=\"t2cell13\">Cell 1.3</td>
96
+ <td id=\"t2cell14\">Cell 1.4</td>
97
+ </tr>
98
+ <tr>
99
+ <td colspan=\"3\" id=\"t2cell22\">Cell 2.2</td>
100
+ </tr>
101
+ </tbody>
102
+ </table>
103
+ <table id=\"table3\">
104
+ <tr>
105
+ <th rowspan=\"2\" id=\"t3column11\">Column 1.1</th>
106
+ <th id=\"t3column12\">Column 1.2</th>
107
+ <th id=\"t3column13\">Column 1.3</th>
108
+ <td id=\"t3column14\">Column 1.4</td>
109
+ </tr>
110
+ <tr>
111
+ <th id=\"t3column22\">Column 2.2</th>
112
+ <th colspan=\"2\" id=\"t3column23\">Column 2.3</th>
113
+ </tr>
114
+ <tr>
115
+ <th rowspan=\"2\" id=\"t3cell11\">Cell 1.1</th>
116
+ <td id=\"t3cell12\">Cell 1.2</td>
117
+ <td id=\"t3cell13\">Cell 1.3</td>
118
+ <td id=\"t3cell14\">Cell 1.4</td>
119
+ </tr>
120
+ <tr>
121
+ <td colspan=\"3\" id=\"t3cell22\">Cell 2.2</td>
122
+ </tr>
123
+ </table>
124
+ <label for=\"field1\">Field1</label>
125
+ <input id=\"field1\" type=\"text\" />
126
+ <br />
127
+ <label>
128
+ Field2
129
+ <input name=\"field2\" type=\"text\" />
130
+ </label>
131
+ <br />
132
+ <label for=\"field3\">Field3</label>
133
+ <input id=\"field3\" type=\"text\" aria-label=\"Field 3\" />
134
+ <br />
135
+ <label>Field4</label>
136
+ <input id=\"field4\" type=\"text\" />
137
+ <br />
138
+ <label #{DATA_IGNORE} for=\"field5\">Field5</label>
139
+ <input id=\"field5\" type=\"text\" />
140
+ <br />
141
+ <label for=\"field6\">Field6</label>
142
+ <input id=\"field6\" type=\"text\" #{DATA_IGNORE} />
143
+ <br />
144
+ <div #{DATA_IGNORE}>
145
+ <label for=\"field7\">Field7</label>
146
+ <input id=\"field7\" type=\"text\" />
147
+ </div>
148
+ </body>
149
+ </html>"
150
+ )
151
+ @association =
152
+ Hatemile::Implementation::AccessibleAssociationImplementation.new(
153
+ @html_parser
154
+ )
155
+ end
156
+
157
+ ##
158
+ # Test associate_all_data_cells_with_header_cells method.
159
+ def test_associate_all_data_cells_with_header_cells
160
+ @association.associate_all_data_cells_with_header_cells
161
+ t1column11 = @html_parser.find('[data-id=t1column11]').first_result
162
+ t1column12 = @html_parser.find('#t1column12').first_result
163
+ t1column13 = @html_parser.find('#t1column13').first_result
164
+ t1column14 = @html_parser.find('#t1column14').first_result
165
+ t1column22 = @html_parser.find('#t1column22').first_result
166
+ t1column23 = @html_parser.find('#t1column23').first_result
167
+ t1cell11 = @html_parser.find('#t1cell11').first_result
168
+ t1cell12 = @html_parser.find('#t1cell12').first_result
169
+ t1cell13 = @html_parser.find('[data-id=t1cell13]').first_result
170
+ t1cell14 = @html_parser.find('#t1cell14').first_result
171
+ t1cell22 = @html_parser.find('#t1cell22').first_result
172
+
173
+ assert(t1column11.has_attribute?('scope'))
174
+ assert(t1column12.has_attribute?('scope'))
175
+ assert(!t1column13.has_attribute?('scope'))
176
+ assert(!t1column14.has_attribute?('scope'))
177
+ assert(t1column22.has_attribute?('scope'))
178
+ assert(t1column23.has_attribute?('scope'))
179
+ assert(t1cell11.has_attribute?('scope'))
180
+ assert(!t1cell12.has_attribute?('scope'))
181
+ assert_equal('col', t1column11.get_attribute('scope'))
182
+ assert_equal('col', t1column12.get_attribute('scope'))
183
+ assert_equal('col', t1column22.get_attribute('scope'))
184
+ assert_equal('col', t1column23.get_attribute('scope'))
185
+ assert_equal('row', t1cell11.get_attribute('scope'))
186
+ assert_equal(
187
+ t1column11.get_attribute('id'),
188
+ t1cell11.get_attribute('headers')
189
+ )
190
+ assert(!t1cell12.has_attribute?('headers'))
191
+ assert_equal(
192
+ %w[t1column23 t1cell11].to_set,
193
+ t1cell13.get_attribute('headers').split.to_set
194
+ )
195
+ assert_equal(
196
+ %w[t1column23 t1cell11].to_set,
197
+ t1cell14.get_attribute('headers').split.to_set
198
+ )
199
+ assert_equal(
200
+ %w[t1column12 t1column22 t1column23 t1cell11].to_set,
201
+ t1cell22.get_attribute('headers').split.to_set
202
+ )
203
+
204
+ assert_nil(@html_parser.find('#table2 [headers]').first_result)
205
+ assert_nil(@html_parser.find('#table3 [headers]').first_result)
206
+ end
207
+
208
+ ##
209
+ # Test associate_all_labels_with_fields method.
210
+ def test_associate_all_labels_with_fields
211
+ field1 = @html_parser.find('#field1').first_result
212
+ field2 = @html_parser.find('[name="field2"]').first_result
213
+ field3 = @html_parser.find('#field3').first_result
214
+ field4 = @html_parser.find('#field4').first_result
215
+ field5 = @html_parser.find('#field5').first_result
216
+ field6 = @html_parser.find('#field6').first_result
217
+ field7 = @html_parser.find('#field7').first_result
218
+
219
+ @association.associate_all_labels_with_fields
220
+
221
+ label1 = @html_parser.find(
222
+ "##{field1.get_attribute('aria-labelledby')}"
223
+ ).first_result
224
+ label2 = @html_parser.find(
225
+ "##{field2.get_attribute('aria-labelledby')}"
226
+ ).first_result
227
+ label3 = @html_parser.find(
228
+ "##{field3.get_attribute('aria-labelledby')}"
229
+ ).first_result
230
+
231
+ assert(field1.has_attribute?('aria-label'))
232
+ assert(field1.has_attribute?('aria-labelledby'))
233
+ assert_equal('Field1', field1.get_attribute('aria-label'))
234
+ assert_equal('field1', label1.get_attribute('for'))
235
+
236
+ assert(field2.has_attribute?('aria-label'))
237
+ assert(field2.has_attribute?('aria-labelledby'))
238
+ assert_equal('Field2', field2.get_attribute('aria-label'))
239
+ assert_equal(
240
+ field2,
241
+ @html_parser.find("##{label2.get_attribute('for')}").first_result
242
+ )
243
+
244
+ assert(field3.has_attribute?('aria-label'))
245
+ assert(field3.has_attribute?('aria-labelledby'))
246
+ assert_equal('Field 3', field3.get_attribute('aria-label'))
247
+ assert_equal('field3', label3.get_attribute('for'))
248
+
249
+ assert(!field4.has_attribute?('aria-label'))
250
+ assert(!field4.has_attribute?('aria-labelledby'))
251
+ assert(!field5.has_attribute?('aria-label'))
252
+ assert(!field5.has_attribute?('aria-labelledby'))
253
+ assert(!field6.has_attribute?('aria-label'))
254
+ assert(!field6.has_attribute?('aria-labelledby'))
255
+ assert(!field7.has_attribute?('aria-label'))
256
+ assert(!field7.has_attribute?('aria-labelledby'))
257
+ end
258
+ end
@@ -0,0 +1,518 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+ require 'test/unit'
16
+ require 'test/unit/assertions'
17
+
18
+ require File.join(
19
+ File.dirname(File.dirname(__FILE__)),
20
+ 'lib',
21
+ 'hatemile',
22
+ 'implementation',
23
+ 'accessible_css_implementation'
24
+ )
25
+ require File.join(
26
+ File.dirname(File.dirname(__FILE__)),
27
+ 'lib',
28
+ 'hatemile',
29
+ 'util',
30
+ 'configure'
31
+ )
32
+ require File.join(
33
+ File.dirname(File.dirname(__FILE__)),
34
+ 'lib',
35
+ 'hatemile',
36
+ 'util',
37
+ 'html',
38
+ 'nokogiri',
39
+ 'nokogiri_html_dom_parser'
40
+ )
41
+ require File.join(
42
+ File.dirname(File.dirname(__FILE__)),
43
+ 'lib',
44
+ 'hatemile',
45
+ 'util',
46
+ 'css',
47
+ 'rcp',
48
+ 'rcp_parser'
49
+ )
50
+
51
+ ##
52
+ # Test methods of Hatemile::Implementation::AccessibleCSSImplementation class.
53
+ class TestAccessibleCSSImplementation < Test::Unit::TestCase
54
+ ##
55
+ # The name of attribute for not modify the elements.
56
+ DATA_IGNORE = 'data-ignoreaccessibilityfix="true"'.freeze
57
+ ##
58
+ # Initialize common attributes used by test methods.
59
+ def setup
60
+ @configure = Hatemile::Util::Configure.new
61
+ end
62
+
63
+ ##
64
+ # Test "speak: none" declaration.
65
+ def test_speak_none
66
+ style = "#speak-none-local,
67
+ #speak-none-inherit,
68
+ #speak-none-local-ignore,
69
+ #speak-none-inherit-ignore {
70
+ speak: none;
71
+ }"
72
+ html_parser = Hatemile::Util::Html::NokogiriLib::NokogiriHTMLDOMParser.new(
73
+ "<!DOCTYPE html>
74
+ <html>
75
+ <head>
76
+ <title>HaTeMiLe Tests</title>
77
+ <meta charset=\"UTF-8\" />
78
+ </head>
79
+ <body>
80
+ <span id=\"speak-none-local\">Not speak this text.</span>
81
+ <div id=\"speak-none-inherit\">
82
+ Not speak <strong>this text.</strong>
83
+ </div>
84
+ <span id=\"speak-none-local-ignore\" #{DATA_IGNORE}>
85
+ Not speak this text.
86
+ </span>
87
+ <div id=\"speak-none-inherit-ignore\" #{DATA_IGNORE}>
88
+ Not speak <strong>this text.</strong>
89
+ </div>
90
+ </body>
91
+ </html>"
92
+ )
93
+ css_parser = Hatemile::Util::Css::Rcp::RCPParser.new(style)
94
+ css = Hatemile::Implementation::AccessibleCSSImplementation.new(
95
+ html_parser,
96
+ css_parser,
97
+ @configure
98
+ )
99
+ css.provide_all_speak_properties
100
+ speak_none_local = html_parser.find('#speak-none-local').first_result
101
+ speak_none_inherit = html_parser.find('#speak-none-inherit').first_result
102
+ speak_none_local_ignore = html_parser.find(
103
+ '#speak-none-local-ignore'
104
+ ).first_result
105
+
106
+ assert(speak_none_local.has_attribute?('role'))
107
+ assert_equal('presentation', speak_none_local.get_attribute('role'))
108
+ assert(speak_none_local.has_attribute?('aria-hidden'))
109
+ assert_equal('true', speak_none_local.get_attribute('aria-hidden'))
110
+
111
+ speak_none_inherit.get_children_elements.each do |child|
112
+ assert(child.has_attribute?('role'))
113
+ assert_equal('presentation', child.get_attribute('role'))
114
+ assert(child.has_attribute?('aria-hidden'))
115
+ assert_equal('true', child.get_attribute('aria-hidden'))
116
+ end
117
+
118
+ assert(!speak_none_local_ignore.has_attribute?('role'))
119
+ assert(!speak_none_local_ignore.has_attribute?('aria-hidden'))
120
+ assert_nil(
121
+ html_parser.find('#speak-none-inherit-ignore [role]').first_result
122
+ )
123
+ assert_nil(
124
+ html_parser.find('#speak-none-inherit-ignore [aria-hidden]').first_result
125
+ )
126
+ end
127
+
128
+ ##
129
+ # Test "speak: normal" declaration.
130
+ def test_speak_normal
131
+ style = "#speak-none-local,
132
+ #speak-none-inherit,
133
+ #speak-none-local-ignore,
134
+ #speak-none-inherit-ignore {
135
+ speak: none;
136
+ }
137
+ span, div {
138
+ speak: normal;
139
+ }"
140
+ html_parser = Hatemile::Util::Html::NokogiriLib::NokogiriHTMLDOMParser.new(
141
+ "<!DOCTYPE html>
142
+ <html>
143
+ <head>
144
+ <title>HaTeMiLe Tests</title>
145
+ <meta charset=\"UTF-8\" />
146
+ </head>
147
+ <body>
148
+ <span id=\"speak-none-local\">Speak this text.</span>
149
+ <div id=\"speak-none-inherit\">
150
+ Speak <strong>this text.</strong>
151
+ </div>
152
+ <span id=\"speak-none-local-ignore\" #{DATA_IGNORE}>
153
+ Speak this text.
154
+ </span>
155
+ <div id=\"speak-none-inherit-ignore\" #{DATA_IGNORE}>
156
+ Speak <strong>this text.</strong>
157
+ </div>
158
+ </body>
159
+ </html>"
160
+ )
161
+ css_parser = Hatemile::Util::Css::Rcp::RCPParser.new(style)
162
+ css = Hatemile::Implementation::AccessibleCSSImplementation.new(
163
+ html_parser,
164
+ css_parser,
165
+ @configure
166
+ )
167
+ css.provide_all_speak_properties
168
+
169
+ assert_nil(html_parser.find('body [role]').first_result)
170
+ assert_nil(html_parser.find('body [aria-hidden]').first_result)
171
+ end
172
+
173
+ ##
174
+ # Test "speak-as: spell-out" declaration.
175
+ def test_speak_as_spell_out
176
+ style = "#speak-as-spell-out-local,
177
+ #speak-as-spell-out-inherit,
178
+ #speak-as-spell-out-local-ignore,
179
+ #speak-as-spell-out-inherit-ignore {
180
+ speak-as: spell-out;
181
+ }"
182
+ html_parser = Hatemile::Util::Html::NokogiriLib::NokogiriHTMLDOMParser.new(
183
+ "<!DOCTYPE html>
184
+ <html>
185
+ <head>
186
+ <title>HaTeMiLe Tests</title>
187
+ <meta charset=\"UTF-8\" />
188
+ </head>
189
+ <body>
190
+ <span id=\"speak-as-spell-out-local\">Speak this text.</span>
191
+ <div id=\"speak-as-spell-out-inherit\">
192
+ Speak <strong>this text.</strong>
193
+ </div>
194
+ <span id=\"speak-as-spell-out-local-ignore\" #{DATA_IGNORE}>
195
+ Speak this text.
196
+ </span>
197
+ <div id=\"speak-as-spell-out-inherit-ignore\" #{DATA_IGNORE}>
198
+ Speak <strong>this text.</strong>
199
+ </div>
200
+ </body>
201
+ </html>"
202
+ )
203
+ css_parser = Hatemile::Util::Css::Rcp::RCPParser.new(style)
204
+ css = Hatemile::Implementation::AccessibleCSSImplementation.new(
205
+ html_parser,
206
+ css_parser,
207
+ @configure
208
+ )
209
+ css.provide_all_speak_properties
210
+ speak_as_spell_out_local = html_parser.find(
211
+ '#speak-as-spell-out-local'
212
+ ).first_result
213
+ speak_as_spell_out_inherit = html_parser.find(
214
+ '#speak-as-spell-out-inherit'
215
+ ).first_result
216
+ speak_as_spell_out_local_ignore = html_parser.find(
217
+ '#speak-as-spell-out-local-ignore'
218
+ ).first_result
219
+ speak_as_spell_out_inherit_ignore = html_parser.find(
220
+ '#speak-as-spell-out-inherit-ignore'
221
+ ).first_result
222
+
223
+ assert_equal(
224
+ 'S p e a k t h i s t e x t .',
225
+ speak_as_spell_out_local.get_text_content
226
+ )
227
+ assert_equal(
228
+ 'S p e a k t h i s t e x t .',
229
+ speak_as_spell_out_inherit.get_text_content.strip
230
+ )
231
+ assert_equal(
232
+ 'Speak this text.',
233
+ speak_as_spell_out_local_ignore.get_text_content.strip
234
+ )
235
+ assert_equal(
236
+ 'Speak this text.',
237
+ speak_as_spell_out_inherit_ignore.get_text_content.strip
238
+ )
239
+ end
240
+
241
+ ##
242
+ # Test "speak-as: literal-punctuation" declaration.
243
+ def test_speak_as_literal_punctuation
244
+ style = "#speak-as-lp-local,
245
+ #speak-as-lp-inherit,
246
+ #speak-as-lp-local-ignore,
247
+ #speak-as-lp-inherit-ignore {
248
+ speak-as: literal-punctuation;
249
+ }"
250
+ html_parser = Hatemile::Util::Html::NokogiriLib::NokogiriHTMLDOMParser.new(
251
+ "<!DOCTYPE html>
252
+ <html>
253
+ <head>
254
+ <title>HaTeMiLe Tests</title>
255
+ <meta charset=\"UTF-8\" />
256
+ </head>
257
+ <body>
258
+ <span id=\"speak-as-lp-local\">Speak this text.</span>
259
+ <div id=\"speak-as-lp-inherit\">
260
+ Speak <strong>this text.</strong>
261
+ </div>
262
+ <span id=\"speak-as-lp-local-ignore\" #{DATA_IGNORE}>
263
+ Speak this text.
264
+ </span>
265
+ <div id=\"speak-as-lp-inherit-ignore\" #{DATA_IGNORE}>
266
+ Speak <strong>this text.</strong>
267
+ </div>
268
+ </body>
269
+ </html>"
270
+ )
271
+ css_parser = Hatemile::Util::Css::Rcp::RCPParser.new(style)
272
+ css = Hatemile::Implementation::AccessibleCSSImplementation.new(
273
+ html_parser,
274
+ css_parser,
275
+ @configure
276
+ )
277
+ css.provide_all_speak_properties
278
+ speak_as_lp_local = html_parser.find('#speak-as-lp-local').first_result
279
+ speak_as_lp_inherit = html_parser.find('#speak-as-lp-inherit').first_result
280
+ speak_as_lp_local_ignore = html_parser.find(
281
+ '#speak-as-lp-local-ignore'
282
+ ).first_result
283
+ speak_as_lp_inherit_ignore = html_parser.find(
284
+ '#speak-as-lp-inherit-ignore'
285
+ ).first_result
286
+
287
+ assert_equal(
288
+ 'Speak this text Dot .',
289
+ speak_as_lp_local.get_text_content
290
+ )
291
+ assert_equal(
292
+ 'Speak this text Dot .',
293
+ speak_as_lp_inherit.get_text_content.strip
294
+ )
295
+ assert_equal(
296
+ 'Speak this text.',
297
+ speak_as_lp_local_ignore.get_text_content.strip
298
+ )
299
+ assert_equal(
300
+ 'Speak this text.',
301
+ speak_as_lp_inherit_ignore.get_text_content.strip
302
+ )
303
+ end
304
+
305
+ ##
306
+ # Test "speak-as: no-punctuation" declaration.
307
+ def test_speak_as_no_punctuation
308
+ style = "#speak-as-np-local,
309
+ #speak-as-np-inherit,
310
+ #speak-as-np-local-ignore,
311
+ #speak-as-np-inherit-ignore {
312
+ speak-as: no-punctuation;
313
+ }"
314
+ html_parser = Hatemile::Util::Html::NokogiriLib::NokogiriHTMLDOMParser.new(
315
+ "<!DOCTYPE html>
316
+ <html>
317
+ <head>
318
+ <title>HaTeMiLe Tests</title>
319
+ <meta charset=\"UTF-8\" />
320
+ </head>
321
+ <body>
322
+ <span id=\"speak-as-np-local\">Speak this text.</span>
323
+ <div id=\"speak-as-np-inherit\">
324
+ Speak <strong>this text.</strong>
325
+ </div>
326
+ <span id=\"speak-as-np-local-ignore\" #{DATA_IGNORE}>
327
+ Speak this text.
328
+ </span>
329
+ <div id=\"speak-as-np-inherit-ignore\" #{DATA_IGNORE}>
330
+ Speak <strong>this text.</strong>
331
+ </div>
332
+ </body>
333
+ </html>"
334
+ )
335
+ css_parser = Hatemile::Util::Css::Rcp::RCPParser.new(style)
336
+ css = Hatemile::Implementation::AccessibleCSSImplementation.new(
337
+ html_parser,
338
+ css_parser,
339
+ @configure
340
+ )
341
+ css.provide_all_speak_properties
342
+
343
+ assert_equal(
344
+ '.',
345
+ html_parser.find(
346
+ '#speak-as-np-local [aria-hidden]'
347
+ ).first_result.get_text_content
348
+ )
349
+ assert_equal(
350
+ '.',
351
+ html_parser.find(
352
+ '#speak-as-np-inherit [aria-hidden]'
353
+ ).first_result.get_text_content.strip
354
+ )
355
+ assert_nil(
356
+ html_parser.find('#speak-as-np-local-ignore [aria-hidden]').first_result
357
+ )
358
+ assert_nil(
359
+ html_parser.find('#speak-as-np-inherit-ignore [aria-hidden]').first_result
360
+ )
361
+ end
362
+
363
+ ##
364
+ # Test "speak-as: digits" declaration.
365
+ def test_speak_as_digits
366
+ style = "#speak-as-digits-local,
367
+ #speak-as-digits-inherit,
368
+ #speak-as-digits-local-ignore,
369
+ #speak-as-digits-inherit-ignore {
370
+ speak-as: digits;
371
+ }"
372
+ html_parser = Hatemile::Util::Html::NokogiriLib::NokogiriHTMLDOMParser.new(
373
+ "<!DOCTYPE html>
374
+ <html>
375
+ <head>
376
+ <title>HaTeMiLe Tests</title>
377
+ <meta charset=\"UTF-8\" />
378
+ </head>
379
+ <body>
380
+ <span id=\"speak-as-digits-local\">111</span>
381
+ <div id=\"speak-as-digits-inherit\">
382
+ 123 <strong>456</strong>
383
+ </div>
384
+ <span id=\"speak-as-digits-local-ignore\" #{DATA_IGNORE}>777</span>
385
+ <div id=\"speak-as-digits-inherit-ignore\" #{DATA_IGNORE}>
386
+ 888 <strong>999</strong>
387
+ </div>
388
+ </body>
389
+ </html>"
390
+ )
391
+ css_parser = Hatemile::Util::Css::Rcp::RCPParser.new(style)
392
+ css = Hatemile::Implementation::AccessibleCSSImplementation.new(
393
+ html_parser,
394
+ css_parser,
395
+ @configure
396
+ )
397
+ css.provide_all_speak_properties
398
+ speak_as_digits_local = html_parser.find(
399
+ '#speak-as-digits-local'
400
+ ).first_result
401
+ speak_as_digits_inherit = html_parser.find(
402
+ '#speak-as-digits-inherit'
403
+ ).first_result
404
+ speak_as_digits_local_ignore = html_parser.find(
405
+ '#speak-as-digits-local-ignore'
406
+ ).first_result
407
+ speak_as_digits_inherit_ignore = html_parser.find(
408
+ '#speak-as-digits-inherit-ignore'
409
+ ).first_result
410
+
411
+ assert_equal('1 1 1', speak_as_digits_local.get_text_content.strip)
412
+ assert_equal(
413
+ '1 2 3 4 5 6',
414
+ speak_as_digits_inherit.get_text_content.strip
415
+ )
416
+ assert_equal('777', speak_as_digits_local_ignore.get_text_content.strip)
417
+ assert_equal(
418
+ '888 999',
419
+ speak_as_digits_inherit_ignore.get_text_content.strip
420
+ )
421
+ end
422
+
423
+ ##
424
+ # Test "speak-as: normal" declaration.
425
+ def test_speak_as_normal
426
+ style = "#speak-as-spell-out-local,
427
+ #speak-as-spell-out-inherit,
428
+ #speak-as-spell-out-local-ignore,
429
+ #speak-as-spell-out-inherit-ignore {
430
+ speak-as: spell-out;
431
+ }
432
+ #speak-as-lp-local,
433
+ #speak-as-lp-inherit,
434
+ #speak-as-lp-local-ignore,
435
+ #speak-as-lp-inherit-ignore {
436
+ speak-as: literal-punctuation;
437
+ }
438
+ #speak-as-np-local,
439
+ #speak-as-np-inherit,
440
+ #speak-as-np-local-ignore,
441
+ #speak-as-np-inherit-ignore {
442
+ speak-as: no-punctuation;
443
+ }
444
+ #speak-as-digits-local,
445
+ #speak-as-digits-inherit,
446
+ #speak-as-digits-local-ignore,
447
+ #speak-as-digits-inherit-ignore {
448
+ speak-as: digits;
449
+ }
450
+ span, div {
451
+ speak-as: normal;
452
+ }"
453
+ html_parser = Hatemile::Util::Html::NokogiriLib::NokogiriHTMLDOMParser.new(
454
+ "<!DOCTYPE html>
455
+ <html>
456
+ <head>
457
+ <title>HaTeMiLe Tests</title>
458
+ <meta charset=\"UTF-8\" />
459
+ </head>
460
+ <body>
461
+ <span id=\"speak-as-spell-out-local\">Speak this text.</span>
462
+ <div id=\"speak-as-spell-out-inherit\">
463
+ Speak <strong>this text.</strong>
464
+ </div>
465
+ <span id=\"speak-as-lp-local\">Speak this text.</span>
466
+ <div id=\"speak-as-lp-inherit\">
467
+ Speak <strong>this text.</strong>
468
+ </div>
469
+ <span id=\"speak-as-np-local\">Speak this text.</span>
470
+ <div id=\"speak-as-np-inherit\">
471
+ Speak <strong>this text.</strong>
472
+ </div>
473
+ <span id=\"speak-as-digits-local\">111</span>
474
+ <div id=\"speak-as-digits-inherit\">
475
+ 123 <strong>456</strong>
476
+ </div>
477
+ </body>
478
+ </html>"
479
+ )
480
+ css_parser = Hatemile::Util::Css::Rcp::RCPParser.new(style)
481
+ css = Hatemile::Implementation::AccessibleCSSImplementation.new(
482
+ html_parser,
483
+ css_parser,
484
+ @configure
485
+ )
486
+ css.provide_all_speak_properties
487
+ speak_as_spell_out_local = html_parser.find(
488
+ '#speak-as-spell-out-local'
489
+ ).first_result
490
+ speak_as_spell_out_inherit = html_parser.find(
491
+ '#speak-as-spell-out-inherit'
492
+ ).first_result
493
+ speak_as_lp_local = html_parser.find('#speak-as-lp-local').first_result
494
+ speak_as_lp_inherit = html_parser.find('#speak-as-lp-inherit').first_result
495
+ speak_as_digits_local = html_parser.find(
496
+ '#speak-as-digits-local'
497
+ ).first_result
498
+ speak_as_digits_inherit = html_parser.find(
499
+ '#speak-as-digits-inherit'
500
+ ).first_result
501
+
502
+ assert_equal('Speak this text.', speak_as_spell_out_local.get_text_content)
503
+ assert_equal(
504
+ 'Speak this text.',
505
+ speak_as_spell_out_inherit.get_text_content.strip
506
+ )
507
+ assert_equal('Speak this text.', speak_as_lp_local.get_text_content.strip)
508
+ assert_equal('Speak this text.', speak_as_lp_inherit.get_text_content.strip)
509
+ assert_nil(
510
+ html_parser.find('#speak-as-np-local [aria-hidden]').first_result
511
+ )
512
+ assert_nil(
513
+ html_parser.find('#speak-as-np-inherit [aria-hidden]').first_result
514
+ )
515
+ assert_equal('111', speak_as_digits_local.get_text_content)
516
+ assert_equal('123 456', speak_as_digits_inherit.get_text_content.strip)
517
+ end
518
+ end