tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 );