browser_caching_hyperlink.js (6450B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 function testLinkIndexAtOffset(id, offset, index) { 8 let htAcc = getAccessible(id, [nsIAccessibleHyperText]); 9 is( 10 htAcc.getLinkIndexAtOffset(offset), 11 index, 12 "Wrong link index at offset " + offset + " for ID " + id + "!" 13 ); 14 } 15 16 function testThis( 17 paragraph, 18 docURI, 19 id, 20 charIndex, 21 expectedLinkIndex, 22 expectedAnchors, 23 expectedURIs, 24 valid = true 25 ) { 26 testLinkIndexAtOffset(paragraph, charIndex, expectedLinkIndex); 27 28 let linkAcc = paragraph.getLinkAt(expectedLinkIndex); 29 ok(linkAcc, "No accessible for link " + id + "!"); 30 31 is(linkAcc.valid, valid, `${id} is valid.`); 32 33 let linkIndex = paragraph.getLinkIndex(linkAcc); 34 is(linkIndex, expectedLinkIndex, "Wrong link index for " + id + "!"); 35 36 is(linkAcc.anchorCount, expectedAnchors.length, "Correct number of anchors"); 37 for (let i = 0; i < expectedAnchors.length; i++) { 38 let uri = linkAcc.getURI(i); 39 is( 40 (uri ? uri.spec : "").replace(docURI, ""), 41 expectedURIs[i], 42 `Wrong anchor URI at ${i} for "${id}"` 43 ); 44 is( 45 getAccessibleDOMNodeID(linkAcc.getAnchor(i)), 46 expectedAnchors[i], 47 `Wrong anchor at ${i} for "${id}"` 48 ); 49 } 50 } 51 52 /** 53 * Test hyperlinks 54 */ 55 addAccessibleTask( 56 ` 57 <p id="testParagraph"><br 58 >Simple link:<br 59 ><a id="NormalHyperlink" href="https://www.mozilla.org">Mozilla Foundation</a><br 60 >ARIA link:<br 61 ><span id="AriaHyperlink" role="link" 62 onclick="window.open('https://www.mozilla.org/');" 63 tabindex="0">Mozilla Foundation Home</span><br 64 >Invalid, non-focusable hyperlink:<br 65 ><span id="InvalidAriaHyperlink" role="link" aria-invalid="true" 66 onclick="window.open('https:/www.mozilla.org/');">Invalid link</span><br 67 >Image map:<br 68 ><map name="atoz_map"><area href="https://www.bbc.co.uk/radio4/atoz/index.shtml#b" 69 coords="17,0,30,14" 70 id="b" 71 shape="rect"></area 72 ><area href="https://www.bbc.co.uk/radio4/atoz/index.shtml#a" 73 coords="0,0,13,14" 74 id="a" 75 shape="rect"></area></map 76 ><img width="447" id="imgmap" 77 height="15" 78 usemap="#atoz_map" 79 src="../letters.gif"></img><br 80 >Empty link:<br 81 ><a id="emptyLink" href=""><img src=""></img></a><br 82 >Link with embedded span<br 83 ><a id="LinkWithSpan" href="https://www.heise.de/"><span lang="de">Heise Online</span></a><br 84 >Named anchor, must not have "linked" state for it to be exposed correctly:<br 85 ><a id="namedAnchor" name="named_anchor">This should never be of state_linked</a> 86 </p> 87 `, 88 function (browser, accDoc) { 89 const paragraph = findAccessibleChildByID(accDoc, "testParagraph", [ 90 nsIAccessibleHyperText, 91 ]); 92 is(paragraph.linkCount, 7, "Wrong link count for paragraph!"); 93 94 const docURI = accDoc.URL; 95 // normal hyperlink 96 testThis( 97 paragraph, 98 docURI, 99 "NormalHyperlink", 100 14, 101 0, 102 ["NormalHyperlink"], 103 ["https://www.mozilla.org/"] 104 ); 105 106 // ARIA hyperlink 107 testThis( 108 paragraph, 109 docURI, 110 "AriaHyperlink", 111 27, 112 1, 113 ["AriaHyperlink"], 114 [""] 115 ); 116 117 // ARIA hyperlink with status invalid 118 testThis( 119 paragraph, 120 docURI, 121 "InvalidAriaHyperlink", 122 63, 123 2, 124 ["InvalidAriaHyperlink"], 125 [""], 126 false 127 ); 128 129 // image map, but not its link children. They are not part of hypertext. 130 testThis( 131 paragraph, 132 docURI, 133 "imgmap", 134 76, 135 3, 136 ["b", "a"], 137 [ 138 "https://www.bbc.co.uk/radio4/atoz/index.shtml#b", 139 "https://www.bbc.co.uk/radio4/atoz/index.shtml#a", 140 ] 141 ); 142 143 // empty hyperlink 144 testThis(paragraph, docURI, "emptyLink", 90, 4, ["emptyLink"], [""]); 145 146 // normal hyperlink with embedded span 147 testThis( 148 paragraph, 149 docURI, 150 "LinkWithSpan", 151 116, 152 5, 153 ["LinkWithSpan"], 154 ["https://www.heise.de/"] 155 ); 156 157 // Named anchor 158 testThis(paragraph, docURI, "namedAnchor", 193, 6, ["namedAnchor"], [""]); 159 }, 160 { 161 chrome: true, 162 topLevel: true, 163 iframe: true, 164 remoteIframe: true, 165 } 166 ); 167 168 /** 169 * Test paragraph with link 170 */ 171 addAccessibleTask( 172 ` 173 <p id="p"><a href="http://mozilla.org">mozilla.org</a></p> 174 `, 175 function (browser, accDoc) { 176 // Paragraph with link 177 const p = findAccessibleChildByID(accDoc, "p", [nsIAccessibleHyperText]); 178 const link = p.getLinkAt(0); 179 is(link, p.getChildAt(0), "Wrong link for p2"); 180 is(p.linkCount, 1, "Wrong link count for p2"); 181 }, 182 { 183 chrome: true, 184 topLevel: true, 185 iframe: true, 186 remoteIframe: true, 187 } 188 ); 189 190 /** 191 * Test paragraph with link 192 */ 193 addAccessibleTask( 194 ` 195 <p id="p"><a href="www">mozilla</a><a href="www">mozilla</a><span> te</span><span>xt </span><a href="www">mozilla</a></p> 196 `, 197 function (browser, accDoc) { 198 // Paragraph with link 199 const p = findAccessibleChildByID(accDoc, "p", [nsIAccessibleHyperText]); 200 201 // getLinkIndexAtOffset, causes the offsets to be cached; 202 testLinkIndexAtOffset(p, 0, 0); // 1st 'mozilla' link 203 testLinkIndexAtOffset(p, 1, 1); // 2nd 'mozilla' link 204 testLinkIndexAtOffset(p, 2, -1); // ' ' of ' te' text node 205 testLinkIndexAtOffset(p, 3, -1); // 't' of ' te' text node 206 testLinkIndexAtOffset(p, 5, -1); // 'x' of 'xt ' text node 207 testLinkIndexAtOffset(p, 7, -1); // ' ' of 'xt ' text node 208 testLinkIndexAtOffset(p, 8, 2); // 3d 'mozilla' link 209 testLinkIndexAtOffset(p, 9, 2); // the end, latest link 210 211 // the second pass to make sure link indexes are calculated propertly from 212 // cached offsets. 213 testLinkIndexAtOffset(p, 0, 0); // 1st 'mozilla' link 214 testLinkIndexAtOffset(p, 1, 1); // 2nd 'mozilla' link 215 testLinkIndexAtOffset(p, 2, -1); // ' ' of ' te' text node 216 testLinkIndexAtOffset(p, 3, -1); // 't' of ' te' text node 217 testLinkIndexAtOffset(p, 5, -1); // 'x' of 'xt ' text node 218 testLinkIndexAtOffset(p, 7, -1); // ' ' of 'xt ' text node 219 testLinkIndexAtOffset(p, 8, 2); // 3d 'mozilla' link 220 testLinkIndexAtOffset(p, 9, 2); // the end, latest link 221 }, 222 { 223 chrome: true, 224 topLevel: true, 225 iframe: true, 226 remoteIframe: true, 227 } 228 );