tor-browser

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

browser_attributed_text.js (8838B)


      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 http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 // Test read-only attributed strings
      8 addAccessibleTask(
      9  `<h1>hello <a href="#" id="a1">world</a></h1>
     10   <p>this <b style="color: red; background-color: yellow;" aria-invalid="spelling">is</b> <span style="text-decoration: underline dotted green;">a</span> <a href="#" id="a2">test</a></p>`,
     11  async (browser, accDoc) => {
     12    let macDoc = accDoc.nativeInterface.QueryInterface(
     13      Ci.nsIAccessibleMacInterface
     14    );
     15 
     16    let range = macDoc.getParameterizedAttributeValue(
     17      "AXTextMarkerRangeForUnorderedTextMarkers",
     18      [
     19        macDoc.getAttributeValue("AXStartTextMarker"),
     20        macDoc.getAttributeValue("AXEndTextMarker"),
     21      ]
     22    );
     23 
     24    let attributedText = macDoc.getParameterizedAttributeValue(
     25      "AXAttributedStringForTextMarkerRange",
     26      range
     27    );
     28 
     29    let attributesList = attributedText.map(
     30      ({
     31        string,
     32        AXForegroundColor,
     33        AXBackgroundColor,
     34        AXUnderline,
     35        AXUnderlineColor,
     36        AXHeadingLevel,
     37        AXFont,
     38        AXLink,
     39        AXMarkedMisspelled,
     40      }) => [
     41        string,
     42        AXForegroundColor,
     43        AXBackgroundColor,
     44        AXUnderline,
     45        AXUnderlineColor,
     46        AXHeadingLevel,
     47        AXFont.AXFontSize,
     48        AXLink ? AXLink.getAttributeValue("AXDOMIdentifier") : null,
     49        AXMarkedMisspelled,
     50      ]
     51    );
     52 
     53    Assert.deepEqual(attributesList, [
     54      // string, fg color, bg color, underline, underline color, heading level, font size, link id, misspelled
     55      [
     56        "hello ",
     57        "#000000",
     58        "#ffffff",
     59        undefined,
     60        undefined,
     61        1,
     62        32,
     63        null,
     64        undefined,
     65      ],
     66      ["world", "#0000ee", "#ffffff", 1, "#0000ee", 1, 32, "a1", undefined],
     67      [
     68        "this ",
     69        "#000000",
     70        "#ffffff",
     71        undefined,
     72        undefined,
     73        undefined,
     74        16,
     75        null,
     76        undefined,
     77      ],
     78      [
     79        "is",
     80        "#ff0000",
     81        "#ffff00",
     82        undefined,
     83        undefined,
     84        undefined,
     85        16,
     86        null,
     87        1,
     88      ],
     89      [
     90        " ",
     91        "#000000",
     92        "#ffffff",
     93        undefined,
     94        undefined,
     95        undefined,
     96        16,
     97        null,
     98        undefined,
     99      ],
    100      ["a", "#000000", "#ffffff", 1, "#008000", undefined, 16, null, undefined],
    101      [
    102        " ",
    103        "#000000",
    104        "#ffffff",
    105        undefined,
    106        undefined,
    107        undefined,
    108        16,
    109        null,
    110        undefined,
    111      ],
    112      [
    113        "test",
    114        "#0000ee",
    115        "#ffffff",
    116        1,
    117        "#0000ee",
    118        undefined,
    119        16,
    120        "a2",
    121        undefined,
    122      ],
    123    ]);
    124 
    125    // Test different NSRange parameters for AXAttributedStringForRange
    126    let worldLeaf = findAccessibleChildByID(accDoc, "a1").firstChild;
    127    let wordStaticText = worldLeaf.nativeInterface.QueryInterface(
    128      Ci.nsIAccessibleMacInterface
    129    );
    130    attributedText = wordStaticText.getParameterizedAttributeValue(
    131      "AXAttributedStringForRange",
    132      NSRange(4, 1)
    133    );
    134    is(attributedText.length, 1, "Last character is in single attribute run");
    135    is(attributedText[0].string, "d", "Last character matches");
    136 
    137    attributedText = wordStaticText.getParameterizedAttributeValue(
    138      "AXAttributedStringForRange",
    139      NSRange(5, 1)
    140    );
    141    is(attributedText.length, 0, "Range is past accessible bounds");
    142  }
    143 );
    144 
    145 // Test misspelling in text area
    146 addAccessibleTask(
    147  `<textarea id="t">hello worlf, i love you</textarea>`,
    148  async (browser, accDoc) => {
    149    let textArea = getNativeInterface(accDoc, "t");
    150    let spellDone = waitForEvent(EVENT_TEXT_ATTRIBUTE_CHANGED, "t");
    151    textArea.setAttributeValue("AXFocused", true);
    152 
    153    let attributedText = [];
    154 
    155    // For some internal reason we get several text attribute change events
    156    // before the attributed text returned provides the misspelling attributes.
    157    while (true) {
    158      await spellDone;
    159 
    160      let range = textArea.getAttributeValue("AXVisibleCharacterRange");
    161      attributedText = textArea.getParameterizedAttributeValue(
    162        "AXAttributedStringForRange",
    163        NSRange(...range)
    164      );
    165 
    166      if (attributedText.length != 3) {
    167        spellDone = waitForEvent(EVENT_TEXT_ATTRIBUTE_CHANGED, "t");
    168      } else {
    169        break;
    170      }
    171    }
    172 
    173    ok(attributedText[1].AXMarkedMisspelled);
    174  }
    175 );
    176 
    177 // Test getting a span of attributed text that includes an empty input element.
    178 addAccessibleTask(
    179  `hello <input id="input"> world<button></button>`,
    180  async (browser, accDoc) => {
    181    let macDoc = accDoc.nativeInterface.QueryInterface(
    182      Ci.nsIAccessibleMacInterface
    183    );
    184 
    185    let range = macDoc.getParameterizedAttributeValue(
    186      "AXTextMarkerRangeForUnorderedTextMarkers",
    187      [
    188        macDoc.getAttributeValue("AXStartTextMarker"),
    189        macDoc.getAttributeValue("AXEndTextMarker"),
    190      ]
    191    );
    192 
    193    let attributedText = macDoc.getParameterizedAttributeValue(
    194      "AXAttributedStringForTextMarkerRange",
    195      range
    196    );
    197 
    198    let text = macDoc.getParameterizedAttributeValue(
    199      "AXStringForTextMarkerRange",
    200      range
    201    );
    202 
    203    is(
    204      attributedText.length,
    205      4,
    206      "Should be 4 attribute runs for 2 texts, input and button"
    207    );
    208    is(attributedText[0].string, `hello `, "Attributed string is correct");
    209    ok(
    210      !attributedText[0].AXAttachment,
    211      "Regular string attributes run doesn't have attachment"
    212    );
    213    is(
    214      attributedText[1].AXAttachment.getAttributeValue("AXRole"),
    215      "AXTextField",
    216      "Entry text attribute run has correct attachment"
    217    );
    218    is(
    219      attributedText[3].AXAttachment.getAttributeValue("AXRole"),
    220      "AXButton",
    221      "Button text attribute run has correct attachment"
    222    );
    223    is(text, `hello  world${kEmbedChar}`, "Unattributed string is correct");
    224  }
    225 );
    226 
    227 // Test text fragment.
    228 addAccessibleTask(
    229  `This is a test.`,
    230  async (browser, accDoc) => {
    231    const macDoc = accDoc.nativeInterface.QueryInterface(
    232      Ci.nsIAccessibleMacInterface
    233    );
    234    const range = macDoc.getParameterizedAttributeValue(
    235      "AXTextMarkerRangeForUnorderedTextMarkers",
    236      [
    237        macDoc.getAttributeValue("AXStartTextMarker"),
    238        macDoc.getAttributeValue("AXEndTextMarker"),
    239      ]
    240    );
    241    const attributedText = macDoc.getParameterizedAttributeValue(
    242      "AXAttributedStringForTextMarkerRange",
    243      range
    244    );
    245    is(attributedText.length, 3);
    246    ok(!attributedText[0].AXHighlight);
    247    ok(attributedText[1].AXHighlight);
    248    is(attributedText[1].string, "test");
    249    ok(!attributedText[2].AXHighlight);
    250  },
    251  { urlSuffix: "#:~:text=test" }
    252 );
    253 
    254 // Test the <mark> element.
    255 addAccessibleTask(
    256  `This is a <mark>test</mark>.`,
    257  async function testMark(browser, accDoc) {
    258    const macDoc = accDoc.nativeInterface.QueryInterface(
    259      Ci.nsIAccessibleMacInterface
    260    );
    261    const range = macDoc.getParameterizedAttributeValue(
    262      "AXTextMarkerRangeForUnorderedTextMarkers",
    263      [
    264        macDoc.getAttributeValue("AXStartTextMarker"),
    265        macDoc.getAttributeValue("AXEndTextMarker"),
    266      ]
    267    );
    268    const attributedText = macDoc.getParameterizedAttributeValue(
    269      "AXAttributedStringForTextMarkerRange",
    270      range
    271    );
    272    is(attributedText.length, 3);
    273    ok(!attributedText[0].AXHighlight);
    274    ok(attributedText[1].AXHighlight);
    275    is(attributedText[1].string, "test");
    276    ok(!attributedText[2].AXHighlight);
    277  }
    278 );
    279 
    280 // Test the <mark> element, in conjunction with content that will
    281 // prevent the creation of a text attributes object.
    282 addAccessibleTask(
    283  `<mark>a<button></button>b</mark>`,
    284  async function testMarkNoAttributes(browser, accDoc) {
    285    const macDoc = accDoc.nativeInterface.QueryInterface(
    286      Ci.nsIAccessibleMacInterface
    287    );
    288    const range = macDoc.getParameterizedAttributeValue(
    289      "AXTextMarkerRangeForUnorderedTextMarkers",
    290      [
    291        macDoc.getAttributeValue("AXStartTextMarker"),
    292        macDoc.getAttributeValue("AXEndTextMarker"),
    293      ]
    294    );
    295    const attributedText = macDoc.getParameterizedAttributeValue(
    296      "AXAttributedStringForTextMarkerRange",
    297      range
    298    );
    299    ok(attributedText, "Document has attributed text");
    300    is(attributedText.length, 3, "3 pieces of attributed text exist");
    301 
    302    ok(attributedText[0].AXHighlight, "0th pos text has highlight");
    303    is(attributedText[0].string, "a", "0th pos text is string `a`");
    304 
    305    ok(!attributedText[1].AXHighlight, "1st pos text has no highlight");
    306 
    307    ok(attributedText[2].AXHighlight, "2nd pos text has highlight");
    308    is(attributedText[2].string, "b", "2nd pos text is string `b`");
    309  }
    310 );