Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Toggling taskitems does not work with a password manager installed #2697

Closed
1 of 2 tasks
pkkid opened this issue Apr 10, 2022 · 18 comments
Closed
1 of 2 tasks

Toggling taskitems does not work with a password manager installed #2697

pkkid opened this issue Apr 10, 2022 · 18 comments
Assignees

Comments

@pkkid
Copy link

pkkid commented Apr 10, 2022

What’s the bug you are facing?

When trying to click a task item on or off, it causes an Index out of range error.

Uncaught RangeError: Index 1 out of range for <taskList(taskItem(paragraph("A list item")), taskItem(paragraph("And another one")))>
    at F.child (vendor.002315f8.js:5:26758)
    at F.findIndex (vendor.002315f8.js:5:27443)
    at Te.nodeAt (vendor.002315f8.js:5:40926)
    at index.091b6c06.js:1:2515
    at tabindex.c5bf3f04.js:3:1741
    at Object.command (tabindex.c5bf3f04.js:3:24340)
    at HTMLInputElement.<anonymous> (index.091b6c06.js:1:2476)

How can we reproduce the bug on our side?

  1. Navigate to the TaskItem extension page: https://tiptap.dev/api/nodes/task-item
  2. With dev tools open, attempt to toggle a task item in the example.

What did you expect to happen?

Expect the TaskItem to toggle on and off.

Did you update your dependencies?

  • Yes, I’ve updated my dependencies to use the latest version of all packages.

Are you sponsoring us?

  • Yes, I’m a sponsor. 💖
@pkkid pkkid added the Type: Bug The issue or pullrequest is related to a bug label Apr 10, 2022
@bdbch
Copy link
Contributor

bdbch commented Apr 10, 2022

Thanks for your bug report @pkkid. I wasn't able to reproduce the issue. I tested in the latest versions of:

  • Firefox
  • Chrome
  • Edge

could you specify more information? Which browser or was any devtool extension used while testing it?

@bdbch bdbch self-assigned this Apr 10, 2022
@rfgamaral
Copy link
Contributor

@pkkid Check your browser extensions. I use Enpass password manager, and I believe I noticed the same issue. Disabling the extension solved it for me.

@pkkid
Copy link
Author

pkkid commented Apr 11, 2022

This is in fact the case. I have Bitwarden installed on Google Chrome. If I disable the extension the TaskItems work as expected. I updated this issue title to better reflect the problem.

It's unfortunate that TaskItems will not work if a password manager is installed. I imagine this is not a small subset of internet users. This issue is a weird one because on one hand you want to say this is a Bitwarden and Enpass bug that they need to fix on their end. The chances they can or will fix that issue is probably pretty minimal. On the other hand, one may also argue that putting inputs on the page not wrapped in a form is in fact a bug. While not ideal, it would be nice if there was a workaround in TipTap to get this working.

Searching online I found another project hitting a similar issue, and their workaround seems to be using fake input elements. Is an approach along these lines something TipTap may consider? ..or maybe an option on the extension to use fake inputs? outline/outline#2921

@pkkid pkkid changed the title Toggling TaskItem causes Index out of range error Toggling taskitems does not work with a password manager installed Apr 11, 2022
@rfgamaral
Copy link
Contributor

It's unfortunate that TaskItems will not work if a password manager is installed.

I don't know much about the root cause of this issue, but I don't think this happens with all password manager extensions out there.

This issue is a weird one because on one hand you want to say this is a Bitwarden and Enpass bug that they need to fix on their end.

I'm of the opinion that this should be fixed by them, I even opened an issue about it for Enpass here (I'm actually in the process of migrating to Bitwarden, and it sucks to see that it has the same problem). A browser extensions should never break a website like this. Maybe you could open a similar issue for Bitwarden (minus the ranting 😅)?

@pkkid
Copy link
Author

pkkid commented Apr 11, 2022

I'm of the opinion that this should be fixed by them.

In an ideal world yes, but I imagine this is a huge uphill battle. Now we have at least two password managers reporting these symptoms, as well as several bugs previously reported. I'm sure there are other password managers with similar issues not yet reported. I am not a maintainer in this package, so my opinion shouldn't carry much weight. However, I imagine if there is pretty simple workaround, and it solves a problem for many users, why not incorporate it as an option?

@bdbch
Copy link
Contributor

bdbch commented Apr 12, 2022

The question coming from this is - if browser extensions are breaking a library, is it the libraries responsibility to handle extensions fiddling with the libraries functionality?

If you take a look into the source code:
https://github.com/ueberdosis/tiptap/blob/main/packages/extension-task-item/src/task-item.ts#L107

There is not a lot of magic happening here. If for example the password manager extension is adding custom nodes to input elements (for example input[type="checkbox"] that could lead to problems with prosemirror and it's getPos method since the positions are all mixed up.

I guess it's really on the extension developers side to ignore input fields that are inside contenteditable elements.

@pkkid
Copy link
Author

pkkid commented Apr 12, 2022

Here is a proof of concept that works without using an input element. I'm happy using a modified extension while other people fight to get the password manager apps to fix their bug. Surprisingly the code is simpler as it can use the li state as the source of truth rather than syncing the input state and li state. It however does require the developer style the span to look like an input on their own. - https://codesandbox.io/s/tiptap-task-items-qm797u?file=/src/task-item.cjs.js

@bdbch
Copy link
Contributor

bdbch commented Apr 12, 2022

I'd be against using a hacky non-input solution. Not only because you have to do custom styling for the span but also of the semantics. I digged a bit into the Enpass javascript code and could see that on change they modify the input element by adding a data attribute to the element.

Since Bitwarden is doing something similar (as seen as here: bitwarden/clients#725) I suspect that's the culprit.

@pkkid
Copy link
Author

pkkid commented Apr 12, 2022

I'd be against using a hacky non-input solution.

Understandable. We understand the problem is upstream, as well as have a workaround. I thought there may be a chance that having task-list wrap the list in a <form> element might help these password managers work better, but it didn't help. It be ideal to have a solution that works with real inputs and these password managers, but I ran out of ideas.

Maybe this bug should be closed as UPSTREAM WONTFIX at this point?

@clibu
Copy link

clibu commented Apr 25, 2022

@bdbch @pkkid Bitwarden is clearing the underlying cause of this issue, however I can't see any difference in the TaskItem dom elements whether Bitwarden is enabled or not, doing a Browser Refresh of course.

Best I can work out is that the NodeViewDesc.create( parent, .. ) parent's prop is null instead of the NodeViewDesc for the parent node. The CustomNodeViewDesc() constructor is returning parent=null which is assigned to descObj which is why getPos() is returning undefined.

I appreciate that various Browser Extensions are causing this. It would appear the developers of these extensions are unlikely or possibly unable to resolve the issues affecting TiptTap.

I wonder therefore if the TaskItem Extension can take into account what's going on and handle this issue for us. My gut feeling is a fix lies somewhere in addNodeView().

FYI I reported the same issue here Also see this issue

Unfortunately as is the TaskItem Extension is unusable.

@pkkid
Copy link
Author

pkkid commented Apr 25, 2022

@clibu I moved forward using my own implementation that removes the input elements. It works fine for my own needs, but requires you style it yourself (like everything else in tiptap). I guess that's frowned upon by the thumbs downs above, but it works.. which is better than the default implementation.

@clibu
Copy link

clibu commented Apr 25, 2022

@pkkid Thanks I saw your earlier Codesandbox example which I assume is the same. I may end up using that.

I had used this in an earlier non-Tiptap implementation which also doesn't use an <input> element.

I just tried the ToDo list on https://bangle.dev/ and it also fails with Bitwarden running.

@clibu
Copy link

clibu commented Apr 25, 2022

@pkkid @bdbch I have a solution that retains the <input> element and resolves the Bitwarden issue. Been a long day, I'll post what I've done in the morning. FYI I'm in Australia.

@clibu
Copy link

clibu commented Apr 25, 2022

@pkkid @bdbch Ok this is what I've done.
Removed the checkbox.addEventListener( 'change',.. ) code.
Added: checkbox.tabIndex = -1 after checkbox.type = 'checkbox' in addNodeView() to prevent Tab onto a checkbox.

Added the following exported handleClickOn() function and it to new Editor({editorProps: {}}) as in the comments below.

/** Process click on TaskList item checkbox.
 *
 *  @rem Editor has lost focus by the time we get here. handleClickOn() is called for mouse up event.
 *  @rem Added as a new Editor( { editorProps: { handleClickOn } } ) and then called by runHandlerOnContext() in Prosemirror input.js
 *
 *  @ref https://prosemirror.net/docs/ref/#view.EditorProps.handleClickOn
 */
function handleClickOn( editorView, pos, node, nodePos, event ){
    if ( node.type.name == 'taskItem' && event.target.matches( 'input[type="checkbox"]' ) ){
        editorView.dispatch( editorView.state.tr.setNodeMarkup( nodePos, null, { checked: !node.attrs.checked } ) )
        return true
    }
}

Using handleClickOn() resolved the getPos() issue. The downside is this external dependency. There are likely other ways to resolve the Browser Extensions issue, but this works for me.

@bdbch
Copy link
Contributor

bdbch commented May 13, 2022

Thanks @clibu

I have a little bit on the pipeline right now but I'll check out your solution as soon as I find some time!

@bdbch bdbch removed the Type: Bug The issue or pullrequest is related to a bug label May 13, 2022
@bdbch
Copy link
Contributor

bdbch commented Jun 26, 2022

As far as I can see from your solution is that it's not accessible as you remove tabbing into checkbox elements? I'd say we keep the current implementation - link to your temporary solution and hope that Bitwarden & Enpass are fixing it on their sides.

@bdbch bdbch closed this as completed Jun 26, 2022
@clibu
Copy link

clibu commented Jun 27, 2022

@bdbch I'll revisit why I removed tab into checkbox. That said I just tried using Tab in the example at https://tiptap.dev/api/nodes/task-list and Back Tab removes the first checkbox altogether. Further Undo doesn't restore it. This is with Bitwarden disabled. So it is badly broken.

From my quick check Tasklist is the only element you can Tab into within TipTap and seems quite pointless to me.

@clibu
Copy link

clibu commented Feb 23, 2023

@pkkid @bdbch @rfgamaral From what I can see Bitwarden has now fixed this issue. I was seeing an issue with my work-around where the checkbox and strikethrough were out of sync which got me to revisit this.

Also see: bitwarden/clients#725

I am seeing an issue with the Tiptap code + YJS where changing the taskitem state on the first item in a list changes the strikethrough but not the checkbox on another device. Taskitems after the first work as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants