Drag & Drop broke in v11
Ok so something that broke for me when moving to v11 is drag&drop from both the items tab of the sidebar and from compendiums isn't working. The code I have is:
It works in v10 but in v11 it doesn't seem to. No errors but it doesn't trigger. Thoughts?
89 Replies
You are on your own... as
_onDropItem
is Foundry core API. On a quick cursory glance at foundry.js
it is only found in ActorSheet
which TRL doesn't extend from. I am not sure how things worked in v10 without further examination.
Comprehensive drag and drop support is forthcoming in TRL. You are mixing Foundry core API code right now to accomplish this task.Tx Michael. @solidor have you tackled this? I'm asking because I got the drag-drop stuff working from the titan code originally.
You need to setup data in
defaultOptions
sent to Application
to enable a drop zone and Application._onDrop
is called and from there you dispatch to your own handling. Good time to read up on the Foundry API and or search for the answer as I'm sure there are plenty of examples in the wild on the main forum.ok
_onDrop
is being called I notice but the Item data doesn't seem to have tagged along with the event.You should seriously start looking at
foundry.js
and set up a debugger instance for development so you can set breakpoints in your code and Foundry core code. If you looked at foundry.js
you'd quickly see that the signature is:
You can then take a look at how things are handled for dispatch in ActorSheet
:
data
will have a uuid
property. You can set it to a TJSDocument instance... doc.setFromDataTransfer(data);
I have not moved over to v11 yet as I am waiting for a stable build. However, I think the A5E people were working on a v11 version of their system so you could try asking them.
Looks like v11 stable shipped last month! I'll have to start updating my system
We've had v11 support since day 1 😅
Our drag and drop wasn't affected at all 🤔
The update was pretty seem less
Minus a few hiccups here and there but they're resolved now
I that case yeah A5E is probably a better reference for drag and drop. My own was pretty slap dash and cribbed from another system
I'll probably also need to fix it for my own
Hmm I have updated titan to v11 and haven't noticed any drag and drop issues
Ok so no need for
this.reactive.document
, which is what I was using to get the actor in v10?
The specific problem I'm experiencing is that const data = TextEditor.getDragEventData(event);
is returning an empty object {}
in v11, which is different from when I run the code in v10, in which case the data is present {type: 'Item', uuid: 'Item.gMEGT8uT7cFwwRBA'}
. Seems to only be affecting Items, if I drag an actor for example then the data turns up, which suggests something is perhaps not v11 compatible with the way I'm creating items, I guess.
That wasn't it. I've isolated this problem now. It is the dragDrop
property of defaultOptions
. I have it set to this on both the ItemSheet and the ActorSheet:
This worked fine in v10. However in v11, what happens is that if I include this option on the ItemSheet, then after opening any ItemSheet that has this setting, the drag & drop of Items stops working globally.
So I've removed it from the ItemSheet and kept it on the ActorSheet (because without it the _onDrop
on the ActorSheet doesn't trigger. However, I'm still getting an empty object for the data extracted from the drop. So this is the ActorSheet _onDrop
:
The other weird thing is that this _onDrop
is defined on the ActorSheet, but if I open the ActorSheet and then close it, then drag an item from the sidebar and drop it on the sidebar, the _onDrop
on the ActorSheet triggers, which really doesn't feel right. That doesn't happen if I refresh and then do the same drag & drop without opening the first ActorSheet.
If I use the native ActorSheet, then the drop works:
If instead, I use SvelteApplication
, then the drop does not work:
Is it me? @mleahy
Maybe I shouldn't be trying to use the native drop listenerAn ActorSheet is a Application, so the
dragDrop
Foundry option is available in any Application.
Maybe I shouldn't be trying to use the native drop listenerWell you do have to use the DOM / browser handing for drag and drop at some point. If you mean "native" as the Foundry handling of this then yes mixing core event handling with TRL requires you to understand how to setup and the limitations of the core handling which you don't directly control. For new Foundry oriented features for TRL next up is comprehensive drag and drop support built into TRL + sorting of embedded reactive collections for drag and drop. Until that is available you either need to implement things entirely yourself for basic drag and drop support on depend on the core support.
I was hoping to depend on the core support but it seems that doesn't work when extending
SvelteApplication
in v11, unless I'm misunderstanding something, as illustrated above. The event doesn't contain the data when I extend SvelteApplication
, at least not when queried within the _onDrop
listener overridden from core ActorSheet.
I can get to the event data within the Svelte component itself but then it's not using core.I'd recommend investigating if the data you are receiving from the drop event is correct. You may be likely configuring Foundry wrong or have bad data like you mentioned in a non-converted compendium or whatever was the data problem you recently mentioned amongst other issues. Setting up break points / log statements and evaluating the data being processed seems necessary. I can't comment on any particular changes to the core Foundry handling for v11 if any, but likely things have not changed.
As you saw Solidor mentioned having no problem moving to v11. So, perhaps investigating the Titan code again is worthwhile. The problem definitely sounds like a configuration issue.
This is where you need to apply debugging and more precise investigation IE actual programming versus throwing things at the wall and hoping they work, etc.
Things are in this middle ground right now before any sort of streamlined / official support gets added to TRL, so it is a bit of a pain to have to understand the details of how Foundry works, but trace through the code. The biggest thing is making sure that the drop event data transfer has the correct data in the first place.
Doesn't my example above show that the data is correct? I'm pretty sure it does.
const data = TextEditor.getDragEventData(event);
You need to verify that the data transfer object inside of
event
even has the data you are trying to parse. It's not magic. Go look at the TextEditor.getDragEventData
method and evaluate if it is receiving the data that it expects. If it is not returning anything then something else is wrong in your configuration. Sight unseen I gather that there isn't a proper data transfer object attached to the drop event. If you are dragging things from non-Foundry UI sources you have to properly fill in that data transfer object. If you are trying to drag from core Foundry UI then something else is wrong in configuration or otherwise.
https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API
https://developer.mozilla.org/en-US/docs/Web/API/DataTransferYou need to verify that the data transfer object inside of event even has the data you are trying to parse.I have done so using
event.dataTransfer.getData("text/plain")
:
- It is present in v10 for both core ActorSheet
and SvelteApplication
.
- It is present in v11 for ActorSheet
.
- It is not present in v11 for SvelteApplication
.
If you are trying to drag from core Foundry UIYes I am dragging from core Foundry UI
Sight unseen I gather that there isn't a proper data transfer object attached to the drop eventCorrect but only for v11 using
SvelteApplication
Titan doesn't have this problem, so again perhaps reevaluate that code. As I mentioned maybe you are configuring things wrong. Just because it worked on v10 doesn't mean you weren't configuring things wrong. Perhaps the underlying Foundry code changed. I don't know. Maybe there is a change in the compendium data format on v11 that you need to update your compendium to be compatible if you are dragging from the side bar. If it is a problem dragging from the sidebar for world actors that is more curious, but none of that code is TRL related; it's all core code that you have to figure out where the problem lies. It's probably not with anything TRL / SvelteApplication related as there is no drag and drop handling code in TRL presently on the application side of things; just what is inherited from the core Application class.
With the data transfer object not being defined that is a good indication that something is wrong in your data configuration with the core platform.
But it is defined if I use
ActorSheet
. If it was a configuration issue with core platform then why would that work?As for titan, the system.json says it's still on v10
https://github.com/Solidor777/Titan-VTTRPG/blob/054104f40e22fda3b84817a5d0a32aabc1b247c0/system.json#L14
GitHub
Titan-VTTRPG/system.json at 054104f40e22fda3b84817a5d0a32aabc1b247c...
Contribute to Solidor777/Titan-VTTRPG development by creating an account on GitHub.
Then you are configuring something wrong in the SvelteApplication -> Application connection. ActorSheet is a Application as well. I can't help you debug the core Foundry code in this case from my time availability to the problem likely lies on your side and not TRL. Nothing being configured in this particular approach has much to do w/ TRL.
Re: Titan. You can just install it and change the compatible field locally to v11. If Titan for v10 works on v11 without changes particularly around core drag and drop support it strongly indicates that something is wrong on your side.
Mixing the core event handling w/ TRL around drag and drop support is a use at your own risk / need to investigate problems. LIke I said eventually there will be easier to use built in support in TRL, but until that is available you are interfacing w/ core Foundry code.
I assume you may have
essential-svelte-esm
installed. In the basic document drop example can you drop in an actor or any document in your system? Then try dnd5e dropping into that example. It works over here without any changes to TRL / demo code from v10 to v11, so document data is properly defined. The demo code processes drop event / data transfer directly via TJSDocument. If the data transfer object is missing there then something fishy is going on from the Foundry side of things not filling in the data transfer object correctly.
Maybe your actor document data has a problem; though probably not because you are getting data transfer from other sources re: ActorSheet.I assume you may have essential-svelte-esm installed. In the basic document drop exampleYes, that drop works in my system but that drop does not use the core foundry
_onDrop
method. Instead it handles the drop inside the Svelte component BasicDocAppShell.svelte
. Whereas what Titan does (and what I've been doing also) is to configure dragDrop
in defaultOptions()
and then use the _onDrop
method, which would be defined in the extension of either ActorSheet
or SvelteApplication
.
The data transfer object is present withiin the Svelte component itself, but it is not present within the Application extension, i.e. SvelteApplication
The problem as mentioned has nothing to do w/ TRL and is between you and Foundry. Go figure it out. Sometimes in programming problems arise and the best way to handle that is the tried and true "divide and conquer" approach.
To read up again on the approach / fundamental debugging skill here is a good article: https://betterprogramming.pub/find-and-fix-bugs-like-a-pro-with-divide-and-conquer-d55f3cf91154
It has been established this has nothing to do w/ TRL and that the fundamental document data transfer object is set for normal drag and drop. It is your job to now go find out why it is not working between the configuration you set for the Application and the core Foundry code. You are likely doing something wrong and there is not much I can do on my side to help you.
I don't think that's correct, because I'm not having this issue if I use the core ActorSheet, or core Application class, only if I use SvelteApplication. By your divide and conquer ideas if it's working in core Application but not in SvelteApplication then surely it has something to do with TRL.
So it's not Foundry's code I'm having to dive into and probe, it's TRL code. Specifically it seems to be the Svelte implementation that's causing it to go arwy.
This works:
But if I switch out the template for a svelte Shell, then while
event.transferData
will be filled if accessed within the Svelte component, it will not be filled if accessed within the Application code. So this does not work:
TRL / SvelteApplication extends Application. The drag and drop handling is in Application. Not TRL code. There is no drag and drop handling built into SvelteApplication that isn't from the base class. I just looked and there is no change in core Foundry drag and drop support that I could see between v10 and v11.
You need to read up and understand the core Foundry code and configuration.
Perhaps you need implement these functions... This is taken from
ActorSheet
:
Otherwise by default only the GM can drag and drop.But it seems to me that you're not understanding that it is working, as long as I don't use the svelte template.
You seem to not understand that there is code in Application that you need to configure correctly. That is on your side to figure that out and do any investigation and improve your knowledge of the core Foundry API. There literally is no code in TRL / SvelteApplication that touches drag and drop.
As long as I don't use TRL it works. So I'm not sure how I can configure it better in terms of
knowledge of core Foundry API
– it's all working if I stick to the core Foundry API.
Anyhow. I'll have a go at tracking down why it's going wrong.Anyhow. I'll have a go at tracking down why it's going wrong.That is what you have to do and I have been saying. The drag and drop handler is initialized in the Application constructor. Either you are sending incorrect data to it or are not defining the data or overidden function requirements of the core Application drag and drop handling.
I don't think it's any of that, already divided and conquered that, but I'll figure it out and let you know what I find.
So, I found the likely problem and it is a change to the core
Application._activateCoreListeners
;
In v10 it simply took the the element passed in:
In v11 it does this:
Full v11 method:
SvelteApplication as currently configured passes back the mounted application div and on v11 for a popOut app html[0].parentElement
is the game / top level body element.
With a small adjustment to SvelteApplication that takes into account for the underlying changed code in Foundry the correct application or content div element can be sent.
So it was a change in the core Foundry Application code that is the likely cause. I can fix this in TRL for the upcoming release, but for now the older version will not take into account this core change in v11.
It didn't take me long to find it, but it is a single line change in the core Foundry code that triggers it.Amazing! Is there a way I can patch it in
node_modules
for now? I had a go but edits to the files in @typhonjs-fvtt/runtime/svelte
don't seem to affect the app.
I suppose I can just override that method actuallyI'm working on that right now. You can't override the method as SvelteApplication overrides it to send the mounted element from the Svelte component. You can replace it though and it is one line and I'll post that soon.
Time for me to hit the sack... tx again for the feedback
Update on my end: I found that dragging and dropping onto actor sheets in Titan doesn't work until you drag and drop something from the sheet to somewhere else.
After that it works.
Dunno if that helps at all! Will read through this more thoroughly when I have a chance
@solidor btw I think the implementation of drag and drop in Titan suffers from a problem. It is configured
dragDrop: [{ dragSelector: '.directory-list .item', dropSelector: null }],
I think that means that the dropSelector is window (not sure) and thus all open Applications receive the drop.
The DocumentSheet implementation you have then decides what to do about that... but it was causing weirdness for me like after opening an Actor Sheet, even dropping an item back onto the sidebar would trigger the _onDrop
code in DocumentSheet. So you may need to refine that implementation somewhat.This is a problem from the changed code in Foundry core. I have a solution that takes into account of the core change there are two points where you need to change SvelteApplication.
line 225-226:
line 996 to:
Theses changes take into account the underlying changes in
Application._activateCoreListeners
.Gotcha
.
Of course I'll be shipping the next TRL version imminently, so you can temporarily change that in the
_dist/svelte/application/SvelteApplication.js
.
It would be great if both of you can test that change before I ship TRL. I don't have any sample code that uses the core Application drag and drop handling or time to make any with current deadlines. I did verify that it works by manual inspection.
As can be seen from this situation things can be fragile even with a one line change to the underlying core Foundry internal implementation. To be clear though this is to hook up the underlying core Application event handlers for drag and drop, tabs, and search. SvelteApplication always hooked those up correctly. At least that method hasn't been turned private yet.
Core tab and search filtering support shouldn't be used at all as that kind of thing should be handled in the Svelte components you develop directly; though it would work if you generated the proper HTML in the component template.
Until drag and drop support is added to TRL / SvelteApplication using the core Foundry support in Application is a stop gap. You can also just as easily set that up in any Svelte component as the sheet to handle drag and drop directly in the component.
I'll probably create a slotted TJSDocumentDropZone
component that takes a TJSDocument instance and handles setting things though just not for this release as I don't have time to test it. I only have time to produce the API docs and ship things. However this is pretty easy to create and a good way to handle things inside of the Svelte component / template.
Though this is great that the underlying core listener hook up got fixed.I can test that out later today!
---
I should note that this fix is probably going to have a side effect for v10 support due to the
firstChild
usage which is the header
element actually for normal apps. IE the header element doesn't contain the content element div, so drag and drop will stop working on v10. It's the safest / easiest way to deal with this situation though that will be more reliable moving forward as you can create popout apps that don't have a content
div.
I definitely don't want to put any conditional code checking Foundry version for this into the code... I mean I can, but it would be handy to get a consensus that for the system devs relying on core drag and drop handling now that moving to v11 is fine.
Also this is an interim solution as by the end of the year a full TRL solution will be available that doesn't depend on core. Like I mentioned though creating such a component / solution for your system is fairly trivial.This reminds me of trying to keep Token Action HUD working for titan. Every minor release, functions get renamed or moved around, and I have to spend a few hours getting it to work the way it did before XD
It can be a mess and I guarantee whatever they do for the Application v2 API is going to cause havoc most likely. It'd be nice if there was more collaborative / discussion on the future. There should be, but I expect a fiasco given the historical account of how changes are made to the core platform.
Once official TRL support for drag and drop has arrived it will be a good idea to completely disconnect the core Application event handling support.
@mleahy The change seems to work for me!
Awesome... Yeah.. will lose v10 support, but I think the core drag and drop is only being used by system devs currently.
I will also probably look at refactoring drag drop in TITAN in line with @geoidesic 's advice. Thanks for the tip
Agreed. Thank you for looking into this ^^
@nekrodarkmoon out of curiousity, is there a convenient place I can look in A5E for how you are handling drag / drop?
The core drag and drop connection should only be attempting to add listeners to to the element passed in which is the app div, so not sure about @geoidesic advice on the class targets.
Item drag start
https://github.com/Pjb518/FoundryVTT-Level-Up-Official/blob/main/src/apps/components/Item.svelte#L70
We don't rely on core drop handling
@solidor
I don't think it's a problem, but testing is always good...
Here is the _activateCoreListeners method again:
And the DragDrop.bind method (IE it should only be targeting the app div passed in which is
html
):
Thank you both
Our system is quite close to being ready for
1.0.0
Not to derail the conversation too.. I found a nasty little side effect w/ KeyboardManager in v11 that required a workaround. I think things should be solid at this point.
we also support playing 5e in it without the hassle of the entire 5e module eco-system
and we've got quite a lot of ppl using the system to play 5e
I don't think I've ever touched the keyboard manager or the mouse manger 🤣
And exactly @nekrodarkmoon. It's definitely not recommended to use the core handlers and to add the proper handling into your various document sheet Svelte components. What I'll be coming up with is just an easier pre-made component to handle some of the heavy lifting, but custom coding it is more than fine too.
Our drop stuff needs to be custom built cz we do a lot of handling with how different item types react with the sheet
but also core stuff is kinda meh
They added a blanket check if any element has
:focus
in v11 and TRL has special focus handling that conflicted as it programmatically sets focus to the appropriate app window when selected. This allows proper keyboard navigation inside the app when tab
is pressed and focus trapping, but the v11 update to KeyboardManager doesn't know anything about TRL and there really isn't any focus handling in App v1.focus handling has always been a pain
the core way to sort stuff is also a major pain
UI / UX is not a strong point of the Foundry team as things go.
😄
They've hired a ux/ui designer recently
canvas and all the pixi stuff... not bad... not bad.. so I will throw a bone out there.
so hopefully things will start imporving
It's the programming / implementation side that needs tons of help. I have my fingers crossed that "App v2" is not a homespun framework.
😄
I'll move into #dev-lounge
Yeah.. Easy to derail... 😄
For me SvelteApplication doesn't have a line 996, only goes to line 991.
From package.json:
Well it hasn't worked for me but I thihk that may be because for some reason I don't understand, edits I put into that file don't seem to run. E.g. if I put a console.log into
SvelteApplication.constructor
, it doesn't trigger. The file in question is: systems/mysystem/node_modules/@typhonjs-fvtt/runtime/_dist/svelte/application/SvelteApplication.js
. In fact even if I delete the file, nothing happens, the system still works as before. Bit confused really.If you are running Vite in dev mode it caches the build. Try a production build.
Thanks. I wasn't aware of the
.vite-cache
. Good to know. Yes, I can confirm this patch works!The default for Vite is to hide that in
node_modules/vite
which makes it even more obscure. The config file I provide puts the cache in the top level .vite-cache
so it can be easily deleted if necessary to regenerate.
As mentioned though this change will make things stop working on v10 probably, but since only a handful of system devs are using this approach this should be fine. Eventually there will be a more streamlined way to accomplish this task that is part of TRL and quite likely I will completely disconnect Application._activateCoreListeners
.As mentioned though this change will make things stop working on v10 probablyYep, and anyone who needs both (for whatever reason) can just add a version conditional in. All good.
Until TRL ships without the conditional. 😮 but you could always add it in.. I think there are 2-3 folks maybe using this approach. The next big TRL release should finally address the drag and drop handling in a way that is more pleasant than core.
I've installed the 0.0.23 hot-patch now and I'm still getting some drag&drop weirdness.
If I refresh the page and open an actor sheet for the first time, it all works perfectly.
However, if I close the sheet and open it again, or instead open any other second sheet (be it Actor or Item), then the data no longer is no longer present in the event the next time I drag and drop to an actor.
The
0.0.23
hot patch only fixes the embedded reactive collections / TJSDocument v11 aspects. You will need to update to 0.1.0
for the fixes for v11 regarding hooking into the platform native event handling for drag and drop as that was a somewhat late breaking change / recent thing detected and fixed. You are also doing things in a generally non-supported manner by hooking up the core drag and drop and not implementing your own handling.
I have a feeling moving to 0.1.0
is going to be somewhat difficult for you to do given your coding skill and aspects of refactoring involved. Things haven't changed drastically in import locations. This is not a change in functionality for the most part, just a change in import paths. Use the TRL documentation to provide a guide: https://typhonjs-fvtt-lib.github.io/api-docs/index.html
You may also opt to apply the "hot patch" to your local copy of TRL 0.0.23
as you recognized is possible above.
It is highly recommended that when you switch to 0.1.0
that you do so during a good breaking point in your own project development when you are at a good point / not working on new features.I did apply the hot patch to 0.0.23 by re-installing it but it sounds like from what you're saying that I need
0.1.0
No the manual patch described above in this thread specifically for connecting the core event handlers on v11.
I've had a go at installing
0.1.0
all seems ok and the app launches although I do see in the yarn dev
output, the following:
Which are related to these imports methinks:
Yeah... There is no more
#runtime/svelte/store
package. There are plenty of extended import paths. You will have to change your code to reflect that...
import { TJSDocument } from "@typhonjs-fvtt/runtime/svelte/store";
becomes:
import { TJSDocument } from "@typhonjs-fvtt/runtime/svelte/store/fvtt/document";
Use the API docs provided to search for symbols that are not compiling or source files. When you view a source file in an IDE especially since there are solid type declarations now it should be obvious (underlines, shown differently) which symbols / imports are no longer linking.Ah. Well I've cleared all the import errors but the sheets do not load svelte templates now, just the defaults.
I did delete a bunch of ripple effects because I can't find them in v 0.1.0
Doubt it's related but can't think of anything else.
If you searched the API docs you'd quickly find the new ripple effect import location:
I can't necessarily help you on changes required. It takes a somewhat disciplined approach to do this kind of refactoring though it's nowhere near as bad as say the v8 / v10 Foundry core updates as it is not a change in functionality.
If you start ripping things out and not working from a stable point before you start this process I suspect that you will have problems in general.
Well I've cleared all the import errors but the sheets do not load svelte templates now, just the defaults.Nothing in TRL touches any sort of sheet configuration w/ Foundry core, so perhaps you did something to cause this problem.
I usually get that when an import is wrong. Although no build nor console errors now, so will have to divide and conquer it.
I recall there being a console.error sort of being folded up in Chrome that is attached to DOMContentLoaded I think. Check the very beginning of the console log when reloading and look for a collapsed error.
It also is best to do these changes for
0.1.0
with production builds. Don't run the dev server until things are stable again.hmm. debounce seems problematic
Yes.. You can watch the video overview when I walked through the changes necessary... If you searched the API docs though.. guess what..
That one is slightly tricky as I have just a few top level helper classes for grouping functions together.
Timing
/ debounce
is probably the most used of that general grouping to what is in #runtime/util
.Running the build showed more errors than the dev server. Good shout. Actor sheet is loading svelte again, except for tabs using the filterQuery doodad:
Yeah.. That is one functional change. It's not too big though. For better type support you pass in the base document class as the first parameter. If that is an
Item
you pass in Item
; if ActiveEffect
then use ActiveEffect
; not as a string, but the base Foundry document. For the most part this is just getting rid of the string wrapper around "Item"
-> to just Item
.
You can also just look at the API docs for answers though there shouldn't be too many more aspects like this:
https://typhonjs-fvtt-lib.github.io/api-docs/interfaces/_runtime_svelte_store_fvtt_document.EmbeddedAPI.html#createOk tx. I'll have a look at that tomorrow. 3am here!
Great!
0.1.0
installed and smoke test passed.
And drag & drop is working perfectly now. Muchos gracias! 👏🏻