Skip to content

TypeError on Chrome when passing an array of HTMLElements to api.Hints.create #2319

@extrosoc

Description

@extrosoc

Prelude

First of all, thank you for the wonderful extension!

I don't think this is a known issue:

Error details

SurfingKeys version: 1.17.9
Browser: Chrome 138.0
OS: Windows 11

Context

The issue is not specific to any URL. The sample settings below can be tested on almost any page (e.g. http://www.google.com), as long as it contains HTML links (anchor tags).

Issue

It does not seem to be possible to pass an array of HTMLElements to the api.Hints.create function anymore.

For example, with the following settings:

api.mapkey("f", "Test", function() {
    api.Hints.create(Array.from(document.querySelectorAll("a")), function(element) {
        alert("Clicked link to:\n" + element.href);
    })
});

I get the following error (in the browser console) when I type the "f" key:

Uncaught TypeError: Cannot read properties of null (reading 'shift')
    at HTMLDocument.<anonymous> (content.js:3:30682)
    at n (api.js:1:209)
    at Object.create (api.js:1:35363)
    at Object.normal:f (8f68ece3-a0f8-4668-af78-37890728636f:2:15)
    at Object.callUserFunction (api.js:1:32706)
    at HTMLDocument.<anonymous> (api.js:1:32633)
    at ce (content.js:3:25393)
    at content.js:3:112886
    at at.handleMapKey (content.js:3:45928)
    at content.js:3:49358

Remarks

In the code above, a simple fix would be to use api.Hints.create("a", ...) instead of passing the array of matching elements.
But unfortunately, I use the ability the pass an array of HTMLElements a lot in my settings because for certain websites, CSS selectors are not sufficient to select the right elements. For example, it is not possible to select the "Delete" buttons with a CSS selector in the following HTML (because they have to be selected based on their content):

<div class="email">
    <div>Email 1 content...</div>
    <button>Archive</button>
    <button>Delete</button> <!-- Here "Delete" is the second button in the list -->
    <button>Mark as read</button>
</div>
<div class="email">
    <div>Email 2 content...</div>
    <button>Delete</button> <!-- Here "Delete" is the first button in the list -->
    <button>Move to inbox</button>
</div>

So, for cases like these, I have a getElementsByXPath(xpathExpression) utility function that returns the array of elements matching the specified XPath expression. For example, to select the "Delete" buttons above, I would have used code like this:

api.mapkey("<Space>d", "Delete email", function() {
    api.Hints.create(getElementsByXPath("//button[.='Delete']"), function(element) {
        element.click();
    })
});

But this kind of code does not work anymore: it raises the aforementioned exception.

Other remark: I checked on Firefox and the issue does not seem to be present at the moment, but it is a different version (SurfingKeys 1.17.5 with Firefox 141.0).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions