1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Include test fixture.
6 GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
11 * @extends {ChromeVoxUnitTestBase}
13 function CvoxDomUtilUnitTest() {}
15 CvoxDomUtilUnitTest.prototype = {
16 __proto__: ChromeVoxUnitTestBase.prototype,
21 'cvox.DescriptionUtil',
28 cvox.ChromeVox.msgs = new cvox.TestMsgs();
31 asText_: function(node) {
32 var temp = document.createElement('div');
33 temp.appendChild(node);
34 return temp.innerHTML;
37 assertEqualsAsText_: function(node1, node2) {
38 assertEquals(this.asText_(node1), this.asText_(node2));
41 loadDomUtilTestDoc_: function() {
42 this.loadDoc(function() {/*!
43 <style type="text/css">
44 #display_none { display: none; }
45 #visibility_hidden { visibility: hidden; }
46 #forced_visible { visibility: hidden; }
47 #visibility_collapse { visibility: collapse; }
48 #opacity_zero { opacity: 0; }
49 #opacity_partial { opacity: 0.5; }
50 #opacity_undefined { }
51 #nested_visibility_hide { visibility: hidden; }
52 #nested_visibility_show { visibility: visible; }
53 #nested_display_none { display: none; }
54 #nested_display_block { display: block; }
58 <div id="normal_node">1</div>
59 <div id="display_none">2</div>
60 <div id="visibility_hidden">3</div>
61 <div id="visibility_collapse">3b</div>
62 <div id="opacity_zero">4</div>
63 <div id="opacity_partial">4b</div>
64 <div id="opacity_undefined">5</div>
65 <select id="select_node"><option>5</option></select>
66 <textarea id="textarea">6</textarea>
67 <div id="forced_visible" aria-hidden="false">7</div>
68 <p id="normal_para">----</p>
69 <p id="presentation" role="presentation">----</p>
70 <p id="aria_hidden" aria-hidden="true">----</p>
71 <p id="only_spaces"> </p>
72 <p id="only_tabs"> </p>
73 <p id="only_newlines">
76 <p id="only_nbsp"> </p>
77 <p id="other_entity">&</p>
79 <img id="img_alt" alt="tree">
80 <img id="img_blankalt" alt="">
82 <input id="check" type="checkbox">
83 <input id="check_checked" type="checkbox" checked>
85 <span><p id="a">a</p></span>
86 <span><p id="b">b</p><p id="c">c</p></span>
89 <a id="special_link1" href="http://google.com"><span id="empty_span"></span>
91 <a id="special_link2" href="http://google.com"><span>Text content</span></a>
92 <a id="special_link3"><span></span></a>
94 <div id="nested_visibility_hide">
95 hide<div id="nested_visibility_show">show</div>me
97 <div id="nested_display_none">
98 nothing<div id="nested_display_block">will</div>show
104 TEST_F('CvoxDomUtilUnitTest', 'IsVisible', function() {
105 this.loadDomUtilTestDoc_();
108 var node = $('normal_node');
109 assertEquals(true, cvox.DomUtil.isVisible(node));
110 node = $('display_none');
111 assertEquals(false, cvox.DomUtil.isVisible(node));
112 node = $('visibility_hidden');
113 assertEquals(false, cvox.DomUtil.isVisible(node));
114 node = $('visibility_collapse');
115 assertEquals(false, cvox.DomUtil.isVisible(node));
116 node = $('opacity_zero');
117 assertEquals(false, cvox.DomUtil.isVisible(node));
118 node = $('opacity_partial');
119 assertEquals(true, cvox.DomUtil.isVisible(node));
120 node = $('opacity_undefined');
121 assertEquals(true, cvox.DomUtil.isVisible(node));
122 node = $('forced_visible');
123 assertEquals(true, cvox.DomUtil.isVisible(node));
125 // Nested visibility tests.
126 node = $('nested_visibility_hide');
127 assertEquals(true, cvox.DomUtil.isVisible(node)); // Has visible child.
128 node = $('nested_visibility_hide').childNodes[0];
129 assertEquals(false, cvox.DomUtil.isVisible(node)); // TextNode is invisible.
130 node = $('nested_visibility_show');
131 assertEquals(true, cvox.DomUtil.isVisible(node));
132 node = $('nested_visibility_show').childNodes[0];
133 assertEquals(true, cvox.DomUtil.isVisible(node)); // TextNode is visible.
134 node = $('nested_display_block');
135 assertEquals(false, cvox.DomUtil.isVisible(node));
137 // Options tests (for performance).
138 node = $('nested_display_block');
140 cvox.DomUtil.isVisible(node, {checkAncestors: false}));
141 node = $('nested_visibility_hide');
143 cvox.DomUtil.isVisible(node, {checkDescendants: false}));
146 /** Test determining if a node is a leaf node or not. @export */
147 TEST_F('CvoxDomUtilUnitTest', 'IsLeafNode', function() {
148 this.loadDomUtilTestDoc_();
150 var node = $('normal_node');
151 assertEquals(false, cvox.DomUtil.isLeafNode(node));
152 node = $('display_none');
153 assertEquals(true, cvox.DomUtil.isLeafNode(node));
154 node = $('visibility_hidden');
155 assertEquals(true, cvox.DomUtil.isLeafNode(node));
156 node = $('opacity_zero');
157 assertEquals(true, cvox.DomUtil.isLeafNode(node));
158 node = $('select_node');
159 assertEquals(true, cvox.DomUtil.isLeafNode(node));
160 node = $('textarea');
161 assertEquals(true, cvox.DomUtil.isLeafNode(node));
162 node = $('normal_para');
163 assertEquals(false, cvox.DomUtil.isLeafNode(node));
164 node = $('aria_hidden');
165 assertEquals(true, cvox.DomUtil.isLeafNode(node));
166 node = $('special_link1');
167 assertEquals(true, cvox.DomUtil.isLeafNode(node));
168 node = $('special_link2');
169 assertEquals(true, cvox.DomUtil.isLeafNode(node));
170 node = $('special_link3');
171 assertEquals(false, cvox.DomUtil.isLeafNode(node));
172 node = $('nested_visibility_hide');
173 assertEquals(false, cvox.DomUtil.isLeafNode(node));
176 /** Test determining if a node has content or not. @export */
177 TEST_F('CvoxDomUtilUnitTest', 'HasContent', function() {
178 this.loadDomUtilTestDoc_();
180 var node = $('normal_node');
181 cvox.DomUtil.hasContent(node);
182 assertEquals(true, cvox.DomUtil.hasContent(node));
183 node = $('display_none');
184 assertEquals(false, cvox.DomUtil.hasContent(node));
185 node = $('visibility_hidden');
186 assertEquals(false, cvox.DomUtil.hasContent(node));
187 node = $('opacity_zero');
188 assertEquals(false, cvox.DomUtil.hasContent(node));
189 node = $('select_node');
190 assertEquals(true, cvox.DomUtil.hasContent(node));
191 node = $('textarea');
192 assertEquals(true, cvox.DomUtil.hasContent(node));
193 node = $('normal_para');
194 assertEquals(true, cvox.DomUtil.hasContent(node));
195 // TODO (adu): This test fails. Will inspect.
196 // node = $('presentation');
197 // assertEquals(false, cvox.DomUtil.hasContent(node));
198 node = $('aria_hidden');
199 assertEquals(false, cvox.DomUtil.hasContent(node));
200 node = $('only_spaces');
201 assertEquals(false, cvox.DomUtil.hasContent(node));
202 node = $('only_tabs');
203 assertEquals(false, cvox.DomUtil.hasContent(node));
204 node = $('only_newlines');
205 assertEquals(false, cvox.DomUtil.hasContent(node));
206 node = $('other_entity');
207 assertEquals(true, cvox.DomUtil.hasContent(node));
209 assertEquals(true, cvox.DomUtil.hasContent(node));
211 assertEquals(true, cvox.DomUtil.hasContent(node));
212 node = $('img_blankalt');
213 assertEquals(false, cvox.DomUtil.hasContent(node));
216 /** Test getting a node's state. @export */
217 TEST_F('CvoxDomUtilUnitTest', 'NodeState', function() {
218 this.loadDomUtilTestDoc_();
219 this.appendDoc(function() {/*!
220 <input id="state1_enabled">
221 <input id="state1_disabled" disabled>
222 <button id="state2_enabled">Button</button>
223 <button id="state2_disabled" disabled>Button</button>
224 <textarea id="state3_enabled">Textarea</textarea>
225 <textarea id="state3_disabled" disabled>Textarea</textarea>
226 <select id="state4_enabled"><option>Select</option></select>
227 <select id="state4_disabled" disabled><option>Select</option></select>
228 <div role="button" id="state5_enabled" tabindex="0">ARIAButton</div>
229 <div role="button" id="state5_disabled" tabindex="0" disabled>ARIAButton</div>
231 <input id="state6_enabled">
234 <input id="state6_disabled">
237 var node = $('check');
238 assertEquals('not checked', cvox.DomUtil.getState(node, true));
239 node = $('check_checked');
240 assertEquals('checked', cvox.DomUtil.getState(node, true));
241 node = $('state1_enabled');
242 assertEquals('', cvox.DomUtil.getState(node, true));
243 node = $('state1_disabled');
244 assertEquals('Disabled', cvox.DomUtil.getState(node, true));
245 node = $('state2_enabled');
246 assertEquals('', cvox.DomUtil.getState(node, true));
247 node = $('state2_disabled');
248 assertEquals('Disabled', cvox.DomUtil.getState(node, true));
249 node = $('state3_enabled');
250 assertEquals('', cvox.DomUtil.getState(node, true));
251 node = $('state3_disabled');
252 assertEquals('Disabled', cvox.DomUtil.getState(node, true));
253 node = $('state4_enabled');
254 assertEquals('1 of 1', cvox.DomUtil.getState(node, true));
255 node = $('state4_disabled');
256 assertEquals('1 of 1 Disabled', cvox.DomUtil.getState(node, true));
257 node = $('state5_enabled');
258 assertEquals('', cvox.DomUtil.getState(node, true));
259 node = $('state5_disabled');
260 assertEquals('', cvox.DomUtil.getState(node, true));
261 node = $('state6_enabled');
262 assertEquals('', cvox.DomUtil.getState(node, true));
263 node = $('state6_disabled');
264 assertEquals('Disabled', cvox.DomUtil.getState(node, true));
267 /** Test finding the next/previous leaf node. @export */
268 TEST_F('CvoxDomUtilUnitTest', 'LeafNodeTraversal', function() {
269 this.loadDomUtilTestDoc_();
272 node = cvox.DomUtil.directedNextLeafNode(node);
273 assertEquals('\n ', node.textContent);
274 node = cvox.DomUtil.directedNextLeafNode(node);
275 assertEquals('b', node.textContent);
276 node = cvox.DomUtil.directedNextLeafNode(node);
277 assertEquals('c', node.textContent);
278 node = cvox.DomUtil.previousLeafNode(node);
279 assertEquals('b', node.textContent);
280 node = cvox.DomUtil.previousLeafNode(node);
281 assertEquals('\n ', node.textContent);
282 node = cvox.DomUtil.previousLeafNode(node);
283 assertEquals('a', node.textContent);
286 /** Test finding the label for controls. @export */
287 TEST_F('CvoxDomUtilUnitTest', 'GetLabel', function() {
288 this.loadDoc(function() {/*!
289 <fieldset id="Fieldset">
290 <legend>This is a legend inside a fieldset</legend>
296 <input name="Email" id="Email" size="18" value="" type="text">
300 <input name="Passwd" id="Passwd" size="18" type="password">
301 <input name="PersistentCookie" id="PersistentCookie" type="checkbox">
302 <label for="PersistentCookie" id="PersistentCookieLabel">
305 <input name="signIn" id="signIn" value="Sign in" type="submit">
306 <input id="dummyA" size="18" value="" type="text" title="">
307 <input id="dummyB" size="18" value="" type="text" aria-label="">
311 function getControlText(control) {
312 var description = cvox.DescriptionUtil.getControlDescription(control);
313 return cvox.DomUtil.collapseWhitespace(
314 description.context + ' ' +
315 description.text + ' ' +
316 description.userValue + ' ' +
317 description.annotation);
320 var fieldsetElement = $('Fieldset');
321 assertEquals('This is a legend inside a fieldset',
322 cvox.DomUtil.getName(fieldsetElement, false, false));
324 var usernameField = $('Email');
325 assertEquals('', cvox.DomUtil.getValue(usernameField));
326 assertEquals('Username:',
327 cvox.DomUtil.getControlLabelHeuristics(usernameField));
328 assertEquals('Username: Edit text', getControlText(usernameField));
329 var passwordField = $('Passwd');
330 assertEquals('', cvox.DomUtil.getValue(passwordField));
331 assertEquals('Password:',
332 cvox.DomUtil.getControlLabelHeuristics(passwordField));
333 assertEquals('Password: Password edit text', getControlText(passwordField));
334 var cookieCheckbox = $('PersistentCookie');
335 assertEquals('Stay signed in', cvox.DomUtil.getName(cookieCheckbox));
336 assertEquals('Stay signed in Check box not checked',
337 getControlText(cookieCheckbox));
338 var signinButton = $('signIn');
339 assertEquals('Sign in', cvox.DomUtil.getName(signinButton));
340 assertEquals('Sign in Button', getControlText(signinButton));
341 var dummyInputA = $('dummyA');
342 assertEquals('', cvox.DomUtil.getName(dummyInputA));
343 var dummyInputB = $('dummyB');
344 assertEquals('', cvox.DomUtil.getName(dummyInputB));
346 // The heuristic no longer returns 'Stay signed in' as the label for
347 // the signIn button because 'Stay signed in' is in a label that's
348 // explicitly associated with another control.
349 //assertEquals('Stay signed in ',
350 // cvox.DomUtil.getControlLabelHeuristics(signinButton));
353 /** Test finding the label for controls with a more complex setup. @export */
354 TEST_F('CvoxDomUtilUnitTest', 'GetLabelComplex', function() {
355 this.loadDoc(function() {/*!
356 <table class="bug-report-table">
358 <td class="bug-report-fieldlabel">
359 <input id="page-url-checkbox" type="checkbox">
360 <span id="page-url-label" i18n-content="page-url">Include this URL:</span>
363 <input id="page-url-text" class="bug-report-field" maxlength="200">
367 <table id="user-email-table" class="bug-report-table">
369 <td class="bug-report-fieldlabel">
370 <input id="user-email-checkbox" checked="checked" type="checkbox">
371 <span id="user-email-label">Include this email:</span>
374 <label id="user-email-text" class="bug-report-field"></label>
378 <table class="bug-report-table">
380 <td class="bug-report-fieldlabel">
381 <input id="sys-info-checkbox" checked="checked" type="checkbox">
382 <span id="sysinfo-label">
383 <a id="sysinfo-url" href="#">Send system information</a>
388 <table class="bug-report-table">
390 <td class="bug-report-fieldlabel">
391 <input id="screenshot-checkbox" type="checkbox">
392 <span id="screenshot-label-current">Include the current screenshot:</span>
397 var urlCheckbox = $('page-url-checkbox');
398 assertEquals('Include this URL:',
399 cvox.DomUtil.getControlLabelHeuristics(urlCheckbox));
400 var emailCheckbox = $('user-email-checkbox');
401 assertEquals('Include this email:',
402 cvox.DomUtil.getControlLabelHeuristics(emailCheckbox));
403 var sysCheckbox = $('sys-info-checkbox');
404 assertEquals('Send system information',
405 cvox.DomUtil.getControlLabelHeuristics(sysCheckbox));
408 /**************************************************************/
410 TEST_F('CvoxDomUtilUnitTest', 'EscapedNames', function() {
411 this.loadDoc(function() {/*!
412 <p id="en-title" title="<>"></p>
413 <p id="en-arialabel" aria-label="<>"></p>
414 <img id="en-img" title="<>"></img>
415 <p id="en-double" title="&lt;&gt;"></p>
417 assertEquals('<>', cvox.DomUtil.getName(
419 assertEquals('<>', cvox.DomUtil.getName(
421 assertEquals('<>', cvox.DomUtil.getName(
423 assertEquals('<>', cvox.DomUtil.getName(
427 /** Test a paragraph with plain text. @export */
428 TEST_F('CvoxDomUtilUnitTest', 'SimplePara', function() {
429 this.loadDoc(function() {/*!
430 <p id="simplepara">This is a simple paragraph.</p>
432 var node = $('simplepara');
433 var text = cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(node));
434 assertEquals('This is a simple paragraph.', text);
437 /** Test a paragraph with nested tags. @export */
438 TEST_F('CvoxDomUtilUnitTest', 'NestedPara', function() {
439 this.loadDoc(function() {/*!
440 <p id="nestedpara">This is a <b>paragraph</b> with <i>nested</i> tags.</p>
442 var node = $('nestedpara');
443 var text = cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(node));
444 assertEquals('This is a paragraph with nested tags.', text);
448 * Test a paragraph with nested tags and varying visibility.
451 TEST_F('CvoxDomUtilUnitTest', 'NestedVisibilityPara', function() {
452 this.loadDoc(function() {/*!
453 <style type="text/css">
454 #nested_visibility_paragraph { }
455 #nested_visibility_paragraph .hide { visibility: hidden; }
456 #nested_visibility_paragraph .show { visibility: visible; }
458 <p id="nested_visibility_paragraph">
462 <span class="show"> a sentence.</span>
466 var node = $('nested_visibility_paragraph');
467 var text = cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(node));
468 assertEquals('This is a sentence.', text);
471 /** Test getting text from an IMG node. @export */
472 TEST_F('CvoxDomUtilUnitTest', 'Image', function() {
473 this.loadDoc(function() {/*!
475 <img id="img_noalt" src="rose.png">
476 <img id="img_alt" alt="flower" src="rose.png">
477 <img id="img_title" title="a Flower" src="rose.png">
478 <img id="img_noalt_long"
479 src="777777777777777777777777777777777.png">
483 assertEquals('Image', cvox.DomUtil.getName(node));
484 node = $('img_noalt');
485 assertEquals('rose Image', cvox.DomUtil.getName(node));
487 assertEquals('flower', cvox.DomUtil.getName(node));
488 node = $('img_title');
489 assertEquals('a Flower', cvox.DomUtil.getName(node));
490 node = $('img_noalt_long');
491 assertEquals('Image', cvox.DomUtil.getName(node));
494 /** Test getting text from a select box. @export */
495 TEST_F('CvoxDomUtilUnitTest', 'Select', function() {
496 this.loadDoc(function() {/*!
497 <select id="select_noneselected">
498 <option>Apple</option>
499 <option>Banana</option>
500 <option>Pear</option>
502 <select id="select_bananaselected">
503 <option>Apple</option>
504 <option selected>Banana</option>
505 <option>Pear</option>
509 $('select_noneselected').selectedIndex = -1;
510 var node = $('select_noneselected');
511 assertEquals('', cvox.DomUtil.getValue(node));
512 node = $('select_bananaselected');
513 assertEquals('Banana', cvox.DomUtil.getValue(node));
516 /** Test whether funky html causes getName to go into infinite loop. */
517 TEST_F('CvoxDomUtilUnitTest', 'GetNameInfiniteLoop', function() {
518 this.loadDoc(function() {/*!
525 // intentionally no asserts; if there is an infinite (recursive) loop,
526 // the stack will blow up
528 var label = cvox.DomUtil.getName(node);
531 /** Test getting text from an INPUT control. @export */
532 TEST_F('CvoxDomUtilUnitTest', 'Input', function() {
533 this.loadDoc(function() {/*!
535 <input id="hidden" type="hidden" value="hidden1">
536 <input id="input_img" type="image" src="rose.png">
537 <input id="input_img_alt" type="image" alt="flower" src="rose.png">
538 <input id="submit" type="submit">
539 <input id="submit_withvalue" type="submit" value="Go">
540 <input id="reset" type="reset">
541 <input id="reset_withvalue" type="reset" value="Stop">
542 <input id="button" type="button" value="Button">
543 <input id="checkbox" type="checkbox" value="ignore1">
544 <input id="checkbox_title" type="checkbox" value="ignore1" title="toggle">
545 <input id="radio" type="radio" value="ignore2">
546 <input id="password" type="password" value="dragon">
547 <input id="text" value="my text">
548 <input id="placeholder0" placeholder="Phone number">
549 <input id="placeholder1" title="Phone number">
550 <input id="placeholder2" title="Phone number" placeholder="xxx-yyy-zzzz">
551 <input id="placeholder3" title="Phone number" placeholder="xxx-yyy-zzzz"
552 value="310-555-1212">
556 var node = $('hidden');
557 assertEquals('', cvox.DomUtil.getName(node));
558 node = $('input_img');
559 assertEquals('rose Image', cvox.DomUtil.getName(node));
560 node = $('input_img_alt');
561 assertEquals('flower', cvox.DomUtil.getName(node));
563 assertEquals('Submit', cvox.DomUtil.getName(node));
564 node = $('submit_withvalue');
565 assertEquals('Go', cvox.DomUtil.getName(node));
567 assertEquals('Reset', cvox.DomUtil.getName(node));
568 node = $('reset_withvalue');
569 assertEquals('Stop', cvox.DomUtil.getName(node));
571 assertEquals('Button', cvox.DomUtil.getName(node));
572 node = $('checkbox');
573 assertEquals('', cvox.DomUtil.getName(node));
574 node = $('checkbox_title');
575 assertEquals('toggle', cvox.DomUtil.getName(node));
577 assertEquals('', cvox.DomUtil.getName(node));
578 node = $('password');
579 assertEquals('dot dot dot dot dot dot ', cvox.DomUtil.getValue(node));
581 assertEquals('my text', cvox.DomUtil.getValue(node));
582 node = $('placeholder0');
583 assertEquals('Phone number', cvox.DomUtil.getName(node));
584 node = $('placeholder1');
585 assertEquals('Phone number', cvox.DomUtil.getName(node));
586 node = $('placeholder2');
587 assertEquals('xxx-yyy-zzzz',
588 cvox.DomUtil.getName(node));
589 node = $('placeholder3');
590 assertEquals('310-555-1212 xxx-yyy-zzzz',
591 cvox.DomUtil.getValue(node) + ' ' + cvox.DomUtil.getName(node));
595 /** Test checking if something is a control. @export */
596 TEST_F('CvoxDomUtilUnitTest', 'IsControl', function() {
597 this.loadDoc(function() {/*!
598 <table width="100%" border="0" cellpadding="0" cellspacing="0">
604 <table width="100%" border="0" cellpadding="0" cellspacing="0">
607 <td bgcolor="#3366CC"><img alt="" width="1" height="1"></td>
612 <table width="100%" border="0" cellpadding="0" cellspacing="0">
615 <td bgcolor="#E5ECF9" nowrap="nowrap"><font color="#000000"
616 face="arial,sans-serif" size="+1"><b> Preferences</b>
619 <td align="right" bgcolor="#E5ECF9" nowrap="nowrap">
620 <font color="#000000" face="arial,sans-serif" size="-1">
621 <a href="http://www.google.com/accounts/ManageAccount">Google
622 Account settings</a> | <a href="http://www.google.com/">
623 Preferences Help</a> | <a href="/about.html">About
624 Google</a> </font></td>
633 <table width="100%" border="0" cellpadding="2" cellspacing="0">
635 <tr bgcolor="#E5ECF9">
636 <td><font face="arial,sans-serif" size="-1"><b>Save</b> your
637 preferences when finished and <b>return to search</b>.</font></td>
639 <td align="right"><font face="arial,sans-serif" size="-1">
640 <input value="Save Preferences " name="submit2" type="submit">
646 <h1>Global Preferences</h1><font size="-1">(changes apply to all Google
649 <table width="100%" border="0" cellpadding="0" cellspacing="0">
652 <td bgcolor="#CBDCED"><img alt="" width="1" height="2"></td>
657 <table width="100%" border="0" cellpadding="0" cellspacing="0">
660 <td width="1" bgcolor="#CBDCED"><img alt="" width="2" height="1"></td>
662 <td valign="top" width="175" nowrap="nowrap">
666 <h2>Interface Language</h2>
670 <font face="arial,sans-serif" size="-1">Display Google tips and
671 messages in: <select name="hl">
692 If you do not find your native language in the pulldown above, you
694 help Google create it through our
695 <a href="http://services.google.com/">Google in Your Language
702 <table width="100%" border="0" cellpadding="0" cellspacing="0">
705 <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="1"></td>
709 <td width="1" bgcolor="#CBDCED"><img alt="" width="2" height="1"></td>
711 <td valign="top" width="175" nowrap="nowrap">
715 <h2>Search Language</h2>
720 <font face="arial,sans-serif" size="-1">Prefer pages written in these
721 language(s):</font><br>
723 <table border="0" cellpadding="5" cellspacing="10">
726 <td valign="top" nowrap="nowrap"><font face="arial,sans-serif"
727 size="-1"><label><input name="lr" value="lang_af"
728 onclick="tick()" id="paf" type="checkbox">
729 <span id="taf">Afrikaans</span></label><br>
730 <label><input name="lr" value="lang_ar" onclick="tick()"
731 id="par" type="checkbox"> <span id="tar">Arabic</span></label>
733 <label><input name="lr" value="lang_hy" onclick="tick()"
734 id="phy" type="checkbox"> <span id="thy">Armenian</span>
736 <label><input name="lr" value="lang_be" onclick="tick()"
737 id="pbe" type="checkbox"> <span id="tbe">Belarusian</span>
739 <label><input name="lr" value="lang_bg" onclick="tick()"
740 id="pbg" type="checkbox"> <span id="tbg">Bulgarian</span>
742 <label><input name="lr" value="lang_ca" onclick="tick()"
743 id="pca" type="checkbox"> <span id="tca">Catalan</span>
745 <label><input name="lr" value="lang_zh-CN" onclick="tick()"
746 id="pzh-CN" type="checkbox"> <span id="tzh-CN">
747 Chinese (Simplified)</span></label><br>
748 <label><input name="lr" value="lang_zh-TW" onclick="tick()"
749 id="pzh-TW" type="checkbox"> <span id="tzh-TW">
750 Chinese (Traditional)</span></label><br>
751 <label><input name="lr" value="lang_hr" onclick="tick()"
752 id="phr" type="checkbox"> <span id="thr">Croatian</span>
754 <label><input name="lr" value="lang_cs" onclick="tick()"
755 id="pcs" type="checkbox"> <span id="tcs">Czech</span>
757 <label><input name="lr" value="lang_da" onclick="tick()"
758 id="pda" type="checkbox"> <span id="tda">Danish</span>
760 <label><input name="lr" value="lang_nl" onclick="tick()"
761 id="pnl" type="checkbox"> <span id="tnl">Dutch</span>
769 </table><a name="loc" id="loc"></a>
771 <table width="100%" border="0" cellpadding="0" cellspacing="0">
774 <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="1"></td>
778 <td width="1" bgcolor="#CBDCED"><img alt="" width="2" height="1"></td>
780 <td valign="top" width="175" nowrap="nowrap">
790 <div style="color: rgb(204, 0, 0); display: none;" id="locerr">
791 <span id="lem"><font face="arial,sans-serif" size="-1">The location
792 <b>X</b> was not recognized.</font></span>
793 <font face="arial,sans-serif" size="-1"><br>
795 Suggestions:<br></font>
798 <li><font face="arial,sans-serif" size="-1">Make sure all street
799 and city names are spelled correctly.</font></li>
801 <li><font face="arial,sans-serif" size="-1">Make sure the address
802 included a city and state.</font></li>
804 <li><font face="arial,sans-serif" size="-1">Try entering a Zip
809 <div style="color: rgb(204, 0, 0); display: none;" id="locterr">
810 <font face="arial,sans-serif" size="-1">Please enter a valid US
815 <div style="color: rgb(204, 0, 0); display: none;" id="locserr">
816 <font face="arial,sans-serif" size="-1">Server error. Please try
819 </div><font face="arial,sans-serif" size="-1">Use as the default
820 location in Google Maps, customized search results, and other Google
822 <input name="uulo" value="1" type="hidden"><input name="muul"
823 value="4_20" type="hidden"><input name="luul" size="60" value=""
825 This location is saved on this computer.
826 <a href="/support/websearch/bin/answer.py?answer=35892&hl=en">
834 <table width="100%" border="0" cellpadding="0" cellspacing="0">
837 <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="1"></td>
841 <td rowspan="2" width="1" bgcolor="#CBDCED">
842 <img alt="" width="2" height="1"></td>
844 <td width="175" nowrap="nowrap">
847 <h2>SafeSearch Filtering</h2>
850 <font face="arial,sans-serif" size="-1">
851 <a href="http://www.google.com/">
852 Google's SafeSearch</a> blocks web pages containing explicit sexual
853 content from appearing in search results.</font></td>
856 <td width="175" nowrap="nowrap"> </td>
858 <div style="margin-bottom: 1.2em; font: smaller arial,sans-serif;">
859 <input id="stf" name="safeui" value="on" type="radio">
860 <label for="stf">Use strict filtering (Filter both explicit
861 text and explicit images)</label><br>
862 <input id="modf" name="safeui" value="images" checked="checked"
863 type="radio"><label for="modf">Use moderate
864 filtering (Filter explicit images only - default
865 behavior)</label><br>
866 <input id="nof" name="safeui" value="off" type="radio">
867 <label for="nof">Do not filter my search results</label>
869 <p style="margin-bottom: 1.2em; font-size: smaller;">This will apply
870 strict filtering to all searches from this computer using Firefox.
871 <a href="http://www.google.com/">Learn more</a></p>
876 <table width="100%" border="0" cellpadding="0" cellspacing="0">
879 <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="1"></td>
883 <td width="1" bgcolor="#CBDCED"><img alt="" width="2" height="1"></td>
885 <td valign="top" width="175" nowrap="nowrap">
889 <h2>Number of Results</h2>
893 <font face="arial,sans-serif" size="-1">Google's default (10 results)
894 provides the fastest results.<br>
895 Display <select name="num">
896 <option value="10" selected="selected">
915 </select> results per page.<br>
921 <table width="100%" border="0" cellpadding="0" cellspacing="0">
924 <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="1"></td>
928 <td width="1" bgcolor="#CBDCED"><img alt="" width="2" height="1"></td>
930 <td valign="top" width="175" nowrap="nowrap">
934 <h2>Results Window</h2><a name="safeui" id="safeui"> </a>
938 <font face="arial,sans-serif" size="-1"><input id="nwc" name="newwindow"
939 value="1" type="checkbox"> <label for="nwc">Open
940 search results in a new browser window.</label></font><br>
946 <table width="100%" border="0" cellpadding="0" cellspacing="0">
949 <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="1"></td>
953 <td width="1" bgcolor="#CBDCED"><img alt="" width="2" height="1"></td>
955 <td valign="top" width="175" nowrap="nowrap">
959 <h2>Google Instant</h2>
963 <font face="arial,sans-serif" size="-1"><input id="suggon" name="suggon"
964 value="1" checked="checked" type="radio"><label for="suggon">Use Google
965 Instant predictions and results appear while typing</label><br>
966 <input id="suggmid" name="suggon" value="2" type="radio">
967 <label for="suggmid">Do not use Google Instant</label><br>
969 Signed-in users can remove personalized predictions from their
970 <a href="/history">Web History</a>. <a href="http://www.google.com/">
977 <td colspan="4" bgcolor="#CBDCED"><img alt="" width="1" height="2"></td>
982 var submitButton = document.getElementsByName('submit2')[0];
983 assertEquals(true, cvox.DomUtil.isControl(submitButton));
984 var selectControl = document.getElementsByName('hl')[0];
985 assertEquals(true, cvox.DomUtil.isControl(selectControl));
986 var checkbox = $('paf');
987 assertEquals(true, cvox.DomUtil.isControl(checkbox));
988 var textInput = document.getElementsByName('luul')[0];
989 assertEquals(true, cvox.DomUtil.isControl(textInput));
990 var radioButton = $('suggmid');
991 assertEquals(true, cvox.DomUtil.isControl(radioButton));
992 var h1Elem = document.getElementsByTagName('h1');
993 assertEquals(false, cvox.DomUtil.isControl(h1Elem));
996 /** Test if something is an ARIA control. @export */
997 TEST_F('CvoxDomUtilUnitTest', 'IsAriaControl', function() {
998 this.loadDoc(function() {/*!
999 <li id="cb1" role="checkbox" tabindex="0" aria-checked="false"
1000 aria-describedby="cond desc1">
1003 <li id="larger1" role="button" tabindex="0" aria-pressed="false"
1004 aria-labelledby="larger_label">+</li>
1005 <li id="r1" role="radio" tabindex="-1" aria-checked="false">Thai</li>
1006 <li id="treeitem1" role="treeitem" tabindex="-1">Oranges</li>
1008 var checkbox = $('cb1');
1009 assertEquals(true, cvox.DomUtil.isControl(checkbox));
1010 var button = $('larger1');
1011 assertEquals(true, cvox.DomUtil.isControl(button));
1012 var radio = $('r1');
1013 assertEquals(true, cvox.DomUtil.isControl(radio));
1014 var treeitem = $('treeitem1');
1015 assertEquals(false, cvox.DomUtil.isControl(treeitem));
1018 /** Test if something is an focusable. @export */
1019 TEST_F('CvoxDomUtilUnitTest', 'IsFocusable', function() {
1020 this.loadDoc(function() {/*!
1021 <a id="focus_link" href="#">Link</a>
1022 <a id="focus_anchor">Unfocusable anchor</a>
1023 <input id="focus_input" value="Input" />
1024 <select id="focus_select"><option>Select</option></select>
1025 <button id="focus_button1">Button</button>
1026 <button id="focus_button2" tabindex="-1">Button 2</button>
1027 <button id="focus_button3" tabindex="0">Button 3</button>
1028 <button id="focus_button4" tabindex="1">Button 4</button>
1029 <div id="focus_div1">Div</div>
1030 <div id="focus_div2" tabindex="-1">Div 2</div>
1031 <div id="focus_div3" tabindex="0">Div 3</div>
1032 <div id="focus_div4" tabindex="1">Div 4</div>
1035 node = $('focus_link');
1036 assertEquals(true, cvox.DomUtil.isFocusable(node));
1037 node = $('focus_anchor');
1038 assertEquals(false, cvox.DomUtil.isFocusable(node));
1039 node = $('focus_input');
1040 assertEquals(true, cvox.DomUtil.isFocusable(node));
1041 node = $('focus_select');
1042 assertEquals(true, cvox.DomUtil.isFocusable(node));
1043 node = $('focus_button1');
1044 assertEquals(true, cvox.DomUtil.isFocusable(node));
1045 node = $('focus_button2');
1046 assertEquals(true, cvox.DomUtil.isFocusable(node));
1047 node = $('focus_button3');
1048 assertEquals(true, cvox.DomUtil.isFocusable(node));
1049 node = $('focus_button4');
1050 assertEquals(true, cvox.DomUtil.isFocusable(node));
1051 node = $('focus_div1');
1052 assertEquals(false, cvox.DomUtil.isFocusable(node));
1053 node = $('focus_div2');
1054 assertEquals(true, cvox.DomUtil.isFocusable(node));
1055 node = $('focus_div3');
1056 assertEquals(true, cvox.DomUtil.isFocusable(node));
1057 node = $('focus_div4');
1058 assertEquals(true, cvox.DomUtil.isFocusable(node));
1060 // Test it with null.
1061 assertEquals(false, cvox.DomUtil.isFocusable(null));
1063 // Test it with something that's not an element.
1064 assertEquals(false, cvox.DomUtil.isFocusable(new Object()));
1066 // Test it with a Text node.
1067 node = $('focus_button1').firstChild;
1068 assertEquals(false, cvox.DomUtil.isFocusable(node));
1071 /** Some additional tests for getName function. */
1072 TEST_F('CvoxDomUtilUnitTest', 'GetName', function() {
1073 this.loadDoc(function() {/*!
1074 <span id="test-span" aria-labelledby="fake-id">Some text</span>
1075 <label id="label1">One</label>
1076 <label id="label3">Label</label>
1077 <div id="test-div" aria-labelledby="label1 label2 label3"></div>
1079 var node = $('test-span');
1080 // Makes sure we can deal with invalid ids in aria-labelledby.
1081 var text = cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(node));
1082 assertEquals('Some text', text);
1083 node = $('test-div');
1084 text = cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(node));
1085 assertEquals('One Label', cvox.DomUtil.getName(node));
1088 /** Test for getLinkURL. */
1089 TEST_F('CvoxDomUtilUnitTest', 'GetLinkURL', function() {
1090 this.loadDoc(function() {/*!
1091 <a id="l1" name="nohref">Anchor</a>
1092 <a id="l2" href="">Empty link</a>
1093 <a id="l3" href="#">Link to self</a>
1094 <a id="l4" href="http://google.com">Google</a>
1095 <span id="l5" role="link" onClick="javascript:alert('?')">Something</span>
1096 <div id="l6" role="link">Div with link role</a>
1099 assertEquals('', cvox.DomUtil.getLinkURL(node));
1101 assertEquals('', cvox.DomUtil.getLinkURL(node));
1103 assertEquals('Internal link', cvox.DomUtil.getLinkURL(node));
1105 assertEquals('http://google.com', cvox.DomUtil.getLinkURL(node));
1107 assertEquals('Unknown link', cvox.DomUtil.getLinkURL(node));
1109 assertEquals('Unknown link', cvox.DomUtil.getLinkURL(node));
1112 /** Test for isDisabled. */
1113 TEST_F('CvoxDomUtilUnitTest', 'IsDisabled', function() {
1114 this.loadDoc(function() {/*!
1115 <input id="button1" type="button" value="Press me!"/>
1116 <input id="button2" type="button" value="Don't touch me!" disabled/>
1118 var node = $('button1');
1119 assertEquals(false, cvox.DomUtil.isDisabled(node));
1120 node = $('button2');
1121 assertEquals(true, cvox.DomUtil.isDisabled(node));
1124 /** Test for a tree with aria-expanded attribute. */
1125 TEST_F('CvoxDomUtilUnitTest', 'Tree', function() {
1126 this.loadDoc(function() {/*!
1127 <div id=":0" role="tree" aria-selected="false" aria-expanded="true"
1128 aria-level="0" aria-labelledby=":0.label" tabindex="0"
1129 aria-activedescendant=":1">
1130 <span id=":0.label">Countries</span>
1131 <div class="goog-tree-item" id=":1" role="treeitem" aria-selected="true"
1132 aria-expanded="false" aria-labelledby=":1.label" aria-level="1">
1133 <span id=":1.label">A</span>
1135 <div class="goog-tree-item" id=":2" role="treeitem" aria-selected="false"
1136 aria-expanded="false" aria-labelledby=":2.label" aria-level="1">
1137 <span id=":2.label">B<span>
1139 <div class="goog-tree-item" id=":3" role="treeitem" aria-selected="false"
1140 aria-expanded="true" aria-labelledby=":3.label" aria-level="1">
1141 <span id=":3.label">C</span>
1142 <div class="goog-tree-children" role="group">
1143 <div class="goog-tree-item" id=":3a" role="treeitem"
1144 aria-selected="false" aria-expanded="false"
1145 aria-labelledby=":3a.label" aria-level="2">
1146 <span id=":3a.label">Chile</span>
1148 <div class="goog-tree-item" id=":3b" role="treeitem"
1149 aria-selected="false" aria-expanded="false"
1150 aria-labelledby=":3b.label" aria-level="2">
1151 <span id=":3b.label">China</span>
1153 <div class="goog-tree-item" id=":3c" role="treeitem"
1154 aria-selected="false" aria-expanded="false"
1155 aria-labelledby=":3c.label" aria-level="2">
1156 <span id=":3c.label">Christmas Island</span>
1158 <div class="goog-tree-item" id=":3d" role="treeitem"
1159 aria-selected="false" aria-expanded="false"
1160 aria-labelledby=":3d.label" aria-level="2">
1161 <span id=":3d.label">Cocos (Keeling) Islands</span>
1168 assertEquals('A Collapsed Selected 1 of 3',
1169 cvox.DomUtil.getControlValueAndStateString(node));
1171 assertEquals('A Collapsed Selected 1 of 3',
1172 cvox.DomUtil.getControlValueAndStateString(node));
1174 assertEquals('B Collapsed Not selected 2 of 3',
1175 cvox.DomUtil.getControlValueAndStateString(node));
1177 assertEquals('C Expanded Not selected 3 of 3',
1178 cvox.DomUtil.getControlValueAndStateString(node));
1180 assertEquals('China Collapsed Not selected 2 of 4',
1181 cvox.DomUtil.getControlValueAndStateString(node));
1184 /** Test for tables with different border specifications */
1185 TEST_F('CvoxDomUtilUnitTest', 'TableBorders', function() {
1186 this.loadDoc(function() {/*!
1187 <table id=":0" border="1">
1192 <table id=":1" border="0">
1197 <table id=":2" border="0px">
1202 <table id=":3" frame="box">
1207 <table id=":4" frame="void">
1212 <table id=":5" style="border-width: medium">
1217 <table id=":6" style="border-width: medium; border-style: none">
1222 <table id=":7" style="border-color: red">
1227 <table id=":8" style="border-style: dotted; border-width: 0px">
1232 <table id=":9" style="border-width: 0px">
1237 <table id=":10" style="border: 0px">
1242 <table id=":11" style="border: 0">
1249 assertTrue(cvox.DomUtil.hasBorder(node));
1252 assertFalse(cvox.DomUtil.hasBorder(node));
1255 assertFalse(cvox.DomUtil.hasBorder(node));
1258 assertTrue(cvox.DomUtil.hasBorder(node));
1261 assertFalse(cvox.DomUtil.hasBorder(node));
1264 assertTrue(cvox.DomUtil.hasBorder(node));
1267 assertFalse(cvox.DomUtil.hasBorder(node));
1270 assertTrue(cvox.DomUtil.hasBorder(node));
1273 assertFalse(cvox.DomUtil.hasBorder(node));
1276 assertFalse(cvox.DomUtil.hasBorder(node));
1279 assertFalse(cvox.DomUtil.hasBorder(node));
1282 assertFalse(cvox.DomUtil.hasBorder(node));
1285 /** Tests for shallowChildlessClone */
1286 TEST_F('CvoxDomUtilUnitTest', 'ShallowChildlessClone', function() {
1287 this.loadDoc(function() {/*!
1288 <div id='simple'>asdf</div>
1289 <div id='expectedSimpleClone'>asdf</div>
1290 <div id='oneLevel'><div>asdf</div></div>
1291 <div id='expectedOneLevelClone'><div></div></div>
1292 <div id='withAttrs'><div class="asdf">asdf</div></div>
1293 <div id='expectedWithAttrsClone'><div class="asdf"></div></div>
1296 var simple = $('simple').firstChild;
1297 var expectedSimpleClone = $('expectedSimpleClone').firstChild;
1298 var oneLevel = $('oneLevel').firstChild;
1299 var expectedOneLevelClone = $('expectedOneLevelClone').firstChild;
1300 var withAttrs = $('withAttrs').firstChild;
1301 var expectedWithAttrsClone = $('expectedWithAttrsClone').firstChild;
1303 var simpleClone = cvox.DomUtil.shallowChildlessClone(simple);
1304 this.assertEqualsAsText_(simpleClone, expectedSimpleClone);
1306 var oneLevelClone = cvox.DomUtil.shallowChildlessClone(oneLevel);
1307 this.assertEqualsAsText_(oneLevelClone, expectedOneLevelClone);
1309 var withAttrsClone = cvox.DomUtil.shallowChildlessClone(withAttrs);
1310 this.assertEqualsAsText_(withAttrsClone, expectedWithAttrsClone);
1313 /** Tests for deepClone */
1314 TEST_F('CvoxDomUtilUnitTest', 'DeepClone', function() {
1315 this.loadDoc(function() {/*!
1316 <div id='simple'>asdf</div>
1318 var simpleClone = cvox.DomUtil.deepClone($('simple'));
1319 this.assertEqualsAsText_(simpleClone, $('simple'));
1321 this.loadDoc(function() {/*!
1322 <div id="withAttrs" class="asdf">asdf</div>
1324 var withAttrsClone = cvox.DomUtil.deepClone($('withAttrs'));
1325 this.assertEqualsAsText_(withAttrsClone, $('withAttrs'));
1328 /** Tests for findNode */
1329 TEST_F('CvoxDomUtilUnitTest', 'FindNode', function() {
1330 this.loadDoc(function() {/*!
1333 <a href="#" id="b">b</a>
1336 var f = cvox.DomUtil.findNode;
1337 var node = f($('root'), function(n) {return n.id == 'b';});
1338 assertEquals('b', node.id);
1341 /** Tests for getState for a list */
1342 TEST_F('CvoxDomUtilUnitTest', 'ListLength', function() {
1343 this.loadDoc(function() {/*!
1350 <li aria-setsize="10">A
1351 <li aria-setsize="10">B
1352 <li aria-setsize="10">C
1356 assertEquals('with 3 items',
1357 cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getState(ul1)));
1360 assertEquals('with 10 items',
1361 cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getState(ul2)));
1364 /** Tests for hasLongDesc */
1365 TEST_F('CvoxDomUtilUnitTest', 'HasLongDesc', function() {
1366 this.loadDoc(function() {/*!
1367 <img id="img0" longdesc="desc.html" src="img0.jpg"></img>
1368 <img id="img1" src="img1.jpg"></img>
1370 var img0 = $('img0');
1371 assertEquals(true, cvox.DomUtil.hasLongDesc(img0));
1373 var img1 = $('img1');
1374 assertEquals(false, cvox.DomUtil.hasLongDesc(img1));
1377 /** Tests for various link leaf types. */
1378 TEST_F('CvoxDomUtilUnitTest', 'LinkLeaf', function() {
1379 this.loadDoc(function() {/*!
1380 <a id='leaf' href='google.com'><strong>Click</strong><div>here</div></a>
1381 <a id='non-leaf' href='google.com'>Click <h2>here</h2></a>
1383 var leaf = $('leaf');
1384 var nonLeaf = $('non-leaf');
1385 assertTrue(cvox.DomUtil.isLeafNode(leaf));
1386 assertFalse(cvox.DomUtil.isLeafNode(nonLeaf));
1390 /** Test the value and state of a multiple select. */
1391 TEST_F('CvoxDomUtilUnitTest', 'MultipleSelectValue', function() {
1392 this.loadDoc(function() {/*!
1393 <select id='cars' multiple>
1394 <option value="volvo">Volvo</option>
1395 <option value="saab">Saab</option>
1396 <option value="opel" selected>Opel</option>
1397 <option value="audi" selected>Audi</option>
1400 var cars = $('cars');
1401 assertEquals('Opel to Audi', cvox.DomUtil.getValue(cars));
1402 assertEquals('selected 2 items', cvox.DomUtil.getState(cars));
1407 * Test correctness of elementToPoint.
1409 * Absolute positioning of the container is used to avoid the window of the
1410 * browser being too small to contain the test elements.
1412 TEST_F('CvoxDomUtilUnitTest', 'ElementToPoint', function() {
1413 this.loadDoc(function() {/*!
1414 <div style="position: absolute; top: 0; left: 0">
1415 <a id='one' href='#a'>First</a>
1416 <p id='two'>Some text</p>
1417 <ul><li id='three'>LI</li><li>LI2</li></ul>
1422 var three = $('three');
1424 var oneHitPoint = cvox.DomUtil.elementToPoint(one);
1425 var twoHitPoint = cvox.DomUtil.elementToPoint(two);
1426 var threeHitPoint = cvox.DomUtil.elementToPoint(three);
1428 assertEquals(one, document.elementFromPoint(oneHitPoint.x, oneHitPoint.y));
1429 assertEquals(two, document.elementFromPoint(twoHitPoint.x, twoHitPoint.y));
1431 document.elementFromPoint(threeHitPoint.x, threeHitPoint.y));
1434 /** Tests we compute the correct name for hidden aria labelledby nodes. */
1435 TEST_F('CvoxDomUtilUnitTest', 'HiddenAriaLabelledby', function() {
1436 this.loadDoc(function() {/*!
1437 <span id="acc_name" style="display: none">
1440 <button id="button" aria-labelledby="acc_name">
1442 assertEquals('hello world!',
1443 cvox.DomUtil.getName($('button')));
1446 /** Tests that we compute the correct state for accesskeys. */
1447 TEST_F('CvoxDomUtilUnitTest', 'AccessKey', function() {
1448 this.loadDoc(function() {/*!
1449 <a id='accessKey' href="#f" title="Next page" accesskey="n">Next page</a>
1451 var a = $('accessKey');
1452 assertEquals('has access key, n', cvox.DomUtil.getState(a));
1456 /** Tests that we compute the correct name for ordered listitems. */
1457 TEST_F('CvoxDomUtilUnitTest', 'OrderedListitem', function() {
1458 this.loadDoc(function() {/*!
1460 <li id='ol_li1'>apple
1461 <li id='ol_li2'>orange
1462 <li id='ol_li3'>strawberry
1463 <li id='ol_li4'>banana
1466 var li1 = $('ol_li1');
1467 var li2 = $('ol_li2');
1468 var li3 = $('ol_li3');
1469 var li4 = $('ol_li4');
1470 // Note that whitespace processing happens at a higher layer
1471 // (DescriptionUtil).
1472 assertEquals('1. apple',
1473 cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li1)));
1474 assertEquals('2. orange',
1475 cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li2)));
1476 assertEquals('3. strawberry',
1477 cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li3)));
1478 assertEquals('4. banana',
1479 cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li4)));
1481 $('fruits_ol').style.listStyleType = 'lower-latin';
1483 assertEquals('A. apple',
1484 cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li1)));
1485 assertEquals('B. orange',
1486 cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li2)));
1487 assertEquals('C. strawberry',
1488 cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li3)));
1489 assertEquals('D. banana',
1490 cvox.DomUtil.collapseWhitespace(cvox.DomUtil.getName(li4)));
1493 /** Tests a node with title, and textContent containing only whitespace. */
1494 TEST_F('CvoxDomUtilUnitTest', 'TitleOverridesInnerWhitespace', function() {
1495 this.loadDoc(function() {/*!
1496 <button id="btn1" title="Remove from Chrome">
1497 <span class="lid"></span>
1498 <span class="can"></span>
1501 var btn1 = $('btn1');
1502 assertEquals('Remove from Chrome', cvox.DomUtil.getName(btn1));
1505 /** Test memoization. **/
1506 TEST_F('CvoxDomUtilUnitTest', 'Memoization', function() {
1507 this.loadDoc(function() {/*!
1508 <div id="container">
1512 // Nest divs 100 levels deep.
1513 var container = $('container');
1514 var outer = container;
1515 for (var i = 0; i < 100; i++) {
1516 var inner = document.createElement('div');
1517 outer.appendChild(inner);
1520 var target = document.createElement('p');
1521 target.innerHTML = 'Text';
1522 outer.appendChild(target);
1524 var iterations = 200;
1526 function logTime(msg, fn) {
1527 var t0 = new Date();
1529 console.log(msg + ' elapsed time: ' + (new Date() - t0) + ' ms');
1532 // First, test without memoization.
1533 logTime('No memoization', function() {
1534 container.style.visibility = 'hidden';
1535 for (var i = 0; i < iterations; i++) {
1536 assertFalse(cvox.DomUtil.isVisible(target));
1538 container.style.visibility = 'visible';
1539 for (var i = 0; i < iterations; i++) {
1540 assertTrue(cvox.DomUtil.isVisible(target));
1544 // Now test with memoization enabled.
1545 logTime('With memoization', function() {
1546 cvox.Memoize.scope(function() {
1547 container.style.visibility = 'hidden';
1548 for (var i = 0; i < iterations; i++) {
1549 assertFalse(cvox.DomUtil.isVisible(target));
1552 cvox.Memoize.scope(function() {
1553 container.style.visibility = 'visible';
1554 for (var i = 0; i < iterations; i++) {
1555 assertTrue(cvox.DomUtil.isVisible(target));
1560 // Finally as a sanity check that things are being memoized, turn on
1561 // memoization and show that we get the wrong result if we change the
1562 // DOM and call isVisible again.
1563 cvox.Memoize.scope(function() {
1564 container.style.visibility = 'hidden';
1565 assertFalse(cvox.DomUtil.isVisible(target));
1567 container.style.visibility = 'visible';
1568 // This should be true! It will return the wrong answer because
1569 // we're deliberately leaving memoization on while modifying the DOM.
1570 assertFalse(cvox.DomUtil.isVisible(target));