tor-browser

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

Document-caretPositionFromPoint.tentative.html (16317B)


      1 <!DOCTYPE html>
      2 <html>
      3 <body>
      4 <meta name="author" title="Siye Liu" href="mailto:siliu@microsoft.com">
      5 <meta name="assert" content="Document's caretPositionFromPoint should return a CaretPosition inside Shadow Root which is provided as argument.">
      6 <link rel="help" href="https://www.w3.org/TR/cssom-view-1/#dom-document-caretpositionfrompoint">
      7 <script src="/resources/testharness.js"></script>
      8 <script src="/resources/testharnessreport.js"></script>
      9 <link rel="stylesheet" href="/fonts/ahem.css">
     10 <style>
     11 textarea {
     12  font: 20px/1 Ahem;
     13  border: none;
     14  padding: 0;
     15 }
     16 </style>
     17 
     18 <div id="container"></div>
     19 <script>
     20 
     21 test(() => {
     22    assert_throws_js(TypeError, () => { document.caretPositionFromPoint(5, 5, "foo"); });
     23    assert_throws_js(TypeError, () => { document.caretPositionFromPoint(5, 5, 6); });
     24  }, "document.caretPositionFromPoint() throws when called without the correct parameters");
     25 
     26 test(() => {
     27    container.setHTMLUnsafe(`<span>hello, world</span>`);
     28    const rect = container.firstChild.getBoundingClientRect();
     29    const characterWidth = rect.width / container.textContent.length;
     30    const characterIndex = 2
     31    // Get x and y coordinate at `he|llo, world`.
     32    const x = rect.left + characterWidth * characterIndex;
     33    const y = rect.top + rect.height / 2;
     34    const caretPosition = document.caretPositionFromPoint(x, y, {});
     35    assert_true(caretPosition instanceof CaretPosition);
     36    assert_true(caretPosition.offsetNode instanceof Text);
     37    assert_equals(typeof(caretPosition.offset), "number");
     38    assert_equals(caretPosition.offsetNode, container.firstChild.firstChild);
     39    assert_equals(caretPosition.offset, characterIndex);
     40 }, "document.caretPositionFromPoint() should return a CaretPosition at the specified location");
     41 
     42 test(() => {
     43    container.setHTMLUnsafe(`<input value='text inside input' />`);
     44    const rect = container.firstChild.getBoundingClientRect();
     45    // Get x and y coordinate at left-most location inside input element.
     46    const x = rect.left + 1;
     47    const y = rect.top + rect.height / 2;
     48    const caretPosition = document.caretPositionFromPoint(x, y);
     49    assert_true(caretPosition instanceof CaretPosition);
     50    assert_true(caretPosition.offsetNode instanceof Node);
     51    assert_equals(typeof(caretPosition.offset), "number");
     52    assert_equals(caretPosition.offsetNode, container.firstChild);
     53    assert_equals(caretPosition.offset, 0);
     54 }, "document.caretPositionFromPoint() should return a CaretPosition at the specified location pointing to an input element which is the offsetNode.");
     55 
     56 promise_test(async () => {
     57    container.setHTMLUnsafe(`<textarea rows="3" cols="4">12345678\n901234567890</textarea>`);
     58    await document.fonts.ready;
     59    const rect = container.firstChild.getBoundingClientRect();
     60    // Get x and y coordinate at "1234|5678..."
     61    const x = rect.left + 1;
     62    const y = rect.top + rect.height * 0.5;
     63    const caretPosition = document.caretPositionFromPoint(x, y);
     64    assert_true(caretPosition instanceof CaretPosition);
     65    assert_true(caretPosition.offsetNode instanceof Node);
     66    assert_equals(typeof(caretPosition.offset), "number");
     67    assert_equals(caretPosition.offsetNode, container.firstChild);
     68    assert_equals(caretPosition.offset, 4);
     69 }, "document.caretPositionFromPoint() should return a CaretPosition at the specified location pointing to a textarea element which is the offsetNode.");
     70 
     71 promise_test(async () => {
     72    container.setHTMLUnsafe(`<textarea rows="3" cols="4">12345678\n901234567890</textarea>`);
     73    await document.fonts.ready;
     74    const element = container.firstChild;
     75    const rect = element.getBoundingClientRect();
     76    const fontSize = parseInt(getComputedStyle(element).fontSize.match(/\d+/)[0]);
     77 
     78    // Check a position after a forced break.
     79    const caretPosition = document.caretPositionFromPoint(
     80        rect.left + fontSize + 2, rect.bottom - fontSize / 2);
     81    // caretPosition should point between '9' and '0'.
     82    assert_equals(caretPosition.offsetNode, element);
     83    assert_equals(caretPosition.offset, 10, 'offset');
     84    const caretRect = caretPosition.getClientRect();
     85    assert_equals(caretRect.left, rect.left + fontSize, 'caretRect.left');
     86    assert_greater_than(caretRect.bottom, rect.top + rect.height * 0.9,
     87        'caretRect.bottom');
     88 }, "document.caretPositionFromPoint() for a point after a forced break should return a CaretPosition at the specified location pointing to a textarea element which is the offsetNode.");
     89 
     90 test(() => {
     91    container.setHTMLUnsafe(`a<div id="host"></div>b`);
     92    const shadowRoot = host.attachShadow({mode: 'closed'});
     93    shadowRoot.setHTMLUnsafe(`<span>hello, world</span>`);
     94    const rect = shadowRoot.firstChild.getBoundingClientRect();
     95    const characterWidth = rect.width / shadowRoot.textContent.length;
     96    const characterIndex = 2
     97    // Get x and y coordinate at `he|llo, world`.
     98    const x = rect.left + characterWidth * characterIndex;
     99    const y = rect.top + rect.height / 2;
    100    const caretPosition = document.caretPositionFromPoint(x, y, {shadowRoots: [shadowRoot]});
    101    assert_true(caretPosition instanceof CaretPosition);
    102    assert_true(caretPosition.offsetNode instanceof Text);
    103    assert_equals(typeof(caretPosition.offset), "number");
    104    assert_equals(caretPosition.offsetNode, shadowRoot.firstChild.firstChild);
    105    assert_equals(caretPosition.offset, characterIndex);
    106 }, 'document.caretPositionFromPoint() should return a CaretPosition at the specified location pointing to a closed shadow tree when the shadow tree is specified as an argument');
    107 
    108 test(() => {
    109    container.setHTMLUnsafe(`
    110        <span>abcd</span>
    111        <div id="host">
    112            <template shadowrootmode=open>
    113                <span>hello, world</span>
    114            </template>
    115        </div>efg`);
    116    const shadowRoot = host.shadowRoot;
    117    const spanElement = document.querySelector("span");
    118    const rect = spanElement.getBoundingClientRect();
    119    const characterWidth = rect.width / spanElement.textContent.length;
    120    const characterIndex = 2
    121    // Get x and y coordinate at `ab|cd`.
    122    const x = rect.left + characterWidth * characterIndex;
    123    const y = rect.top + rect.height / 2;
    124    const caretPosition = document.caretPositionFromPoint(x, y, {shadowRoots: [shadowRoot]});
    125    assert_true(caretPosition instanceof CaretPosition);
    126    assert_true(caretPosition.offsetNode instanceof Text);
    127    assert_equals(typeof(caretPosition.offset), "number");
    128    assert_equals(caretPosition.offsetNode, spanElement.firstChild);
    129    assert_equals(caretPosition.offset, characterIndex);
    130 }, 'document.caretPositionFromPoint() should return a CaretPosition at the specified location when the non-intersecting shadow tree is specified as an argument');
    131 
    132 test(() => {
    133    container.setHTMLUnsafe(`
    134        a<div id="host">
    135            <template shadowrootmode=open>
    136                <input value='text inside input' />
    137            </template>
    138        </div>efg`);
    139    const shadowRoot = host.shadowRoot;
    140    const shadowRootInputElement = shadowRoot.querySelector("input");
    141    const rect = shadowRootInputElement.getBoundingClientRect();
    142    // Get x and y coordinate at left-most location inside input element.
    143    const x = rect.left + 1;
    144    const y = rect.top + rect.height / 2;
    145    const caretPosition = document.caretPositionFromPoint(x, y, {shadowRoots: [shadowRoot]});
    146    assert_true(caretPosition instanceof CaretPosition);
    147    assert_true(caretPosition.offsetNode instanceof Node);
    148    assert_equals(typeof(caretPosition.offset), "number");
    149    assert_equals(caretPosition.offsetNode, shadowRootInputElement);
    150    assert_equals(caretPosition.offset, 0);
    151 }, "document.caretPositionFromPoint() should return a CaretPosition at the specified location pointing to an input element when the shadow tree is specified as an argument.");
    152 
    153 test(() => {
    154    container.setHTMLUnsafe(`
    155        a<div id="host">
    156            <template shadowrootmode=open>
    157                <input value='text inside input' />
    158            </template>
    159        </div>efg`);
    160    const shadowRoot = host.shadowRoot;
    161    const shadowRootInputElement = shadowRoot.querySelector("input");
    162    const rect = shadowRootInputElement.getBoundingClientRect();
    163    // Get x and y coordinate at left-most location inside input element.
    164    const x = rect.left + 1;
    165    const y = rect.top + rect.height / 2;
    166    const caretPosition = document.caretPositionFromPoint(x, y, {shadowRoots: []});
    167    assert_true(caretPosition instanceof CaretPosition);
    168    assert_true(caretPosition.offsetNode instanceof Node);
    169    assert_equals(typeof(caretPosition.offset), "number");
    170    assert_equals(caretPosition.offsetNode, container);
    171    assert_equals(caretPosition.offset, 1);
    172 }, "document.caretPositionFromPoint() should return a CaretPosition at the specified location pointing to the input element's shadow host\'s parent when the shadow tree is not specified as an argument.");
    173 
    174 test(() => {
    175    container.setHTMLUnsafe(`
    176        a<div id="host">
    177            <template shadowrootmode=open>
    178                <span>hello, world</span>
    179            </template>
    180        </div>b`);
    181    const shadowRoot = host.shadowRoot;
    182    const shadowRootSpanElement = shadowRoot.querySelector("span");
    183    const rect = shadowRootSpanElement.getBoundingClientRect();
    184    const characterWidth = rect.width / shadowRootSpanElement.textContent.length;
    185    const characterIndex = 2
    186    // Get x and y coordinate at `he|llo, world`.
    187    const x = rect.left + characterWidth * characterIndex;
    188    const y = rect.top + rect.height / 2;
    189    const caretPosition = document.caretPositionFromPoint(x, y);
    190    assert_true(caretPosition instanceof CaretPosition);
    191    assert_true(caretPosition.offsetNode instanceof Node);
    192    assert_equals(typeof(caretPosition.offset), "number");
    193    assert_equals(caretPosition.offsetNode, container);
    194    assert_equals(caretPosition.offset, 1);
    195 }, 'document.caretPositionFromPoint() should return a CaretPosition at the specified location pointing to the shadow host\'s parent when the shadow tree is not specified as an argument');
    196 
    197 test(() => {
    198    container.setHTMLUnsafe(`
    199        a<div id="outerHost">
    200            <template shadowrootmode=open>
    201                <div id="innerHost">
    202                    <template shadowrootmode=open>
    203                        <span>some text</span>
    204                    </template>
    205                </div>
    206                <div>world</div>
    207            </template>
    208        </div>b`);
    209    const outerShadowRoot = outerHost.shadowRoot;
    210    const innerShadowRoot = outerShadowRoot.getElementById('innerHost').shadowRoot;
    211    const innerShadowRootSpanElement = innerShadowRoot.querySelector("span");
    212    const rect = innerShadowRootSpanElement.getBoundingClientRect();
    213    const characterWidth = rect.width / innerShadowRootSpanElement.textContent.length;
    214    const characterIndex = 2
    215    // Get x and y coordinate at `so|me text`.
    216    const x = rect.left + characterWidth * characterIndex;
    217    const y = rect.top + rect.height / 2;
    218    const caretPosition = document.caretPositionFromPoint(x, y);
    219    assert_true(caretPosition instanceof CaretPosition);
    220    assert_true(caretPosition.offsetNode instanceof Node);
    221    assert_equals(typeof(caretPosition.offset), "number");
    222    assert_equals(caretPosition.offsetNode, container);
    223    assert_equals(caretPosition.offset, 1);
    224 }, 'document.caretPositionFromPoint() should return a CaretPosition at the specified location pointing to the outer shadow host\'s parent when the point is in an inner shadow tree and no shadow tree is specified as an argument');
    225 
    226 test(() => {
    227    container.setHTMLUnsafe(`
    228        a<div id="outerHost">
    229            <template shadowrootmode=open>
    230                <div id="innerHost">
    231                    <template shadowrootmode=open>
    232                        <span>some text</span>
    233                    </template>
    234                </div>
    235                <div>world</div>
    236            </template>
    237        </div>b`);
    238    const outerShadowRoot = outerHost.shadowRoot;
    239    const innerShadowRoot = outerShadowRoot.getElementById('innerHost').shadowRoot;
    240    const innerShadowRootSpanElement = innerShadowRoot.querySelector("span");
    241    const rect = innerShadowRootSpanElement.getBoundingClientRect();
    242    const characterWidth = rect.width / innerShadowRootSpanElement.textContent.length;
    243    const characterIndex = 2
    244    // Get x and y coordinate at `so|me text`.
    245    const x = rect.left + characterWidth * characterIndex;
    246    const y = rect.top + rect.height / 2;
    247    const caretPosition = document.caretPositionFromPoint(x, y, {shadowRoots: [innerShadowRoot]});
    248    assert_true(caretPosition instanceof CaretPosition);
    249    assert_true(caretPosition.offsetNode instanceof Text);
    250    assert_equals(typeof(caretPosition.offset), "number");
    251    assert_equals(caretPosition.offsetNode, innerShadowRootSpanElement.firstChild);
    252    assert_equals(caretPosition.offset, characterIndex);
    253 }, 'document.caretPositionFromPoint() should return a CaretPosition at the specified location pointing to the inner shadow tree when the point is in an inner shadow tree and the inner shadow tree is specified as an argument');
    254 
    255 test(() => {
    256    container.setHTMLUnsafe(`
    257        a<div id="outerHost">
    258            <template shadowrootmode=open>
    259                <div id="innerHost">
    260                    <template shadowrootmode=open>
    261                        <span>some text</span>
    262                    </template>
    263                </div>
    264                <div>world</div>
    265            </template>
    266        </div>b`);
    267    const outerShadowRoot = outerHost.shadowRoot;
    268    const innerShadowRoot = outerShadowRoot.getElementById('innerHost').shadowRoot;
    269    const innerShadowRootSpanElement = innerShadowRoot.querySelector("span");
    270    const rect = innerShadowRootSpanElement.getBoundingClientRect();
    271    const characterWidth = rect.width / innerShadowRootSpanElement.textContent.length;
    272    const characterIndex = 2
    273    // Get x and y coordinate at `so|me text`.
    274    const x = rect.left + characterWidth * characterIndex;
    275    const y = rect.top + rect.height / 2;
    276    const caretPosition = document.caretPositionFromPoint(x, y, {shadowRoots: [outerShadowRoot]});
    277    assert_true(caretPosition instanceof CaretPosition);
    278    assert_true(caretPosition.offsetNode instanceof Node);
    279    assert_equals(typeof(caretPosition.offset), "number");
    280    assert_equals(caretPosition.offsetNode, outerShadowRoot);
    281    assert_equals(caretPosition.offset, 1);
    282 }, 'document.caretPositionFromPoint() should return a CaretPosition at the specified location pointing to the outer shadow tree when the point is in an inner shadow tree and the outer shadow tree is specified as an argument');
    283 
    284 test(() => {
    285    container.setHTMLUnsafe(`
    286        a<div id="outerHost">
    287            <template shadowrootmode=open>
    288                <div id="innerHost">
    289                    <template shadowrootmode=open>
    290                        <span>some text</span>
    291                    </template>
    292                </div>
    293                <div>world</div>
    294            </template>
    295        </div>b`);
    296 
    297    const outerShadowRoot = outerHost.shadowRoot;
    298    const innerShadowRoot = outerShadowRoot.getElementById('innerHost').shadowRoot;
    299    const innerShadowRootSpanElement = innerShadowRoot.querySelector("span");
    300    const rect = innerShadowRootSpanElement.getBoundingClientRect();
    301    const characterWidth = rect.width / innerShadowRootSpanElement.textContent.length;
    302    const characterIndex = 2
    303    // Get x and y coordinate at `so|me text`.
    304    const x = rect.left + characterWidth * characterIndex;
    305    const y = rect.top + rect.height / 2;
    306    const caretPosition = document.caretPositionFromPoint(x, y, {shadowRoots: [innerShadowRoot, outerShadowRoot]});
    307    assert_true(caretPosition instanceof CaretPosition);
    308    assert_true(caretPosition.offsetNode instanceof Text);
    309    assert_equals(typeof(caretPosition.offset), "number");
    310    assert_equals(caretPosition.offsetNode, innerShadowRootSpanElement.firstChild);
    311    assert_equals(caretPosition.offset, characterIndex);
    312 }, 'document.caretPositionFromPoint() should return a CaretPosition at the specified location pointing to the inner shadow tree when the point is in an inner shadow tree and the inner shadow tree and the outer shadow tree are specified as an argument');
    313 </script>
    314 </body>
    315 </html>