Search code examples
reactjsgoogle-chrome-extensiondrag-and-dropcontent-scripttrello

How to override drag event listener with chrome extension (content script)?


I am building a Chrome extension which add extra functions to Trello.

The problem I am facing is that Trello somehow disabled the html5 drag and drop, so that when I drag some DOM (which I inject with my extension) with attribute draggable="true" the translucent representation of the draggable elements does not appear.

..

(Dragging the red box, which is <div draggable="true" style="..."></div> does not show the translucent image)

enter image description here

..

By inspecting the page with Chrome DevTool, I see there is a dragstart event listener set to the document.

enter image description here

..

If I remove the dragstart event listener (by clicking the "Remove" button next to it inside the DevTool's Event Listeners window) then the drag works correctly as shown in the screenshot below. (The red box on the right is the translucent representation created by the html5 drag mechanism).

enter image description here

..

So my question is: is there any way to override that dragstart event listener with a chrome extension for the elements that I intend to make draggable?

P.S. I am plaining to use react DnD eventually which is based on the html5 drag mechanism. And apparently, I am using react to build my extension :)

..

Edited: Here are the code from Trello where the dragstart event listener is attached.

n(document).bind("dragstart", function(e) {
  return n(e.target).closest(".ui-draggable, .js-draggable").length > 0
}),

The above code is placed within n(document).ready(function() { /* HERE */ } and n = e("jquery"). (Not 100% sure but seems that n is just jQuery.)

Since the event listener is attached anonymously, it is not possible to remove it afterwards (Correct me if I am wrong).


Solution

  • To begin with, a reminder: JavaScript defined in the page lives in a separate JS context from content scripts (the "isolated world" principle). Read up on that if unfamiliar.

    With that in mind, you have two potential approaches:

    • You can be the fastest gun in the West and attach your listener first, before any of the page's code has a chance to execute, with a run_at: "document_start" content script. From there, you can cancel event propagation so that the page's listener won't receive it.

    • You can remove the listener yourself by injecting into the page context. How to remove it depends on how it was attached, of course.