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:
export default class SvelteDocumentSheet extends SvelteApplication {
async _onDropItem(event, data, actor) {
console.log('_onDropItem');
}
}
export default class SvelteDocumentSheet extends SvelteApplication {
async _onDropItem(event, data, actor) {
console.log('_onDropItem');
}
}
It works in v10 but in v11 it doesn't seem to. No errors but it doesn't trigger. Thoughts?
89 Replies
TyphonJS (Michael)
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.
geoidesic
geoidesic11mo ago
Tx Michael. @solidor have you tackled this? I'm asking because I got the drag-drop stuff working from the titan code originally.
TyphonJS (Michael)
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.
geoidesic
geoidesic11mo ago
ok _onDrop is being called I notice but the Item data doesn't seem to have tagged along with the event.
TyphonJS (Michael)
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:
/**
* Callback actions which occur when a dragged element is dropped on a target.
* @param {DragEvent} event The originating DragEvent
* @protected
*/
_onDrop(event) {}
/**
* Callback actions which occur when a dragged element is dropped on a target.
* @param {DragEvent} event The originating DragEvent
* @protected
*/
_onDrop(event) {}
You can then take a look at how things are handled for dispatch in ActorSheet:
async _onDrop(event) {
const data = TextEditor.getDragEventData(event);
const actor = this.actor;
const allowed = Hooks.call("dropActorSheetData", actor, this, data);
if ( allowed === false ) return;

// Handle different data types
switch ( data.type ) {
case "ActiveEffect":
return this._onDropActiveEffect(event, data);
case "Actor":
return this._onDropActor(event, data);
case "Item":
return this._onDropItem(event, data);
case "Folder":
return this._onDropFolder(event, data);
}
}
async _onDrop(event) {
const data = TextEditor.getDragEventData(event);
const actor = this.actor;
const allowed = Hooks.call("dropActorSheetData", actor, this, data);
if ( allowed === false ) return;

// Handle different data types
switch ( data.type ) {
case "ActiveEffect":
return this._onDropActiveEffect(event, data);
case "Actor":
return this._onDropActor(event, data);
case "Item":
return this._onDropItem(event, data);
case "Folder":
return this._onDropFolder(event, data);
}
}
data will have a uuid property. You can set it to a TJSDocument instance... doc.setFromDataTransfer(data);
Solidor
Solidor11mo ago
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
Nekro Darkmoon
Nekro Darkmoon11mo ago
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
Solidor
Solidor11mo ago
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
geoidesic
geoidesic11mo ago
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:
dragDrop: [{ dragSelector: ".directory-list .item", dropSelector: null }],
dragDrop: [{ dragSelector: ".directory-list .item", dropSelector: null }],
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:
async _onDrop(event) {
const data = TextEditor.getDragEventData(event);
console.log('data', data); //<--- outputs `{}` on v11, but on v10 it outputs `{type: 'Item', uuid: 'Item.gMEGT8uT7cFwwRbA'}`
async _onDrop(event) {
const data = TextEditor.getDragEventData(event);
console.log('data', data); //<--- outputs `{}` on v11, but on v10 it outputs `{type: 'Item', uuid: 'Item.gMEGT8uT7cFwwRbA'}`
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:
export default class MyActorSheet extends ActorSheet {

static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
dragDrop: [{ dragSelector: ".directory-list .item", dropSelector: null }],
});
}

async _onDrop(event) {
const data = TextEditor.getDragEventData(event);
console.log('data: ', data); //<-- outputs {type: 'Item', uuid: 'Item.gMEGT8uT7cFwwRbA'}
}
}
export default class MyActorSheet extends ActorSheet {

static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
dragDrop: [{ dragSelector: ".directory-list .item", dropSelector: null }],
});
}

async _onDrop(event) {
const data = TextEditor.getDragEventData(event);
console.log('data: ', data); //<-- outputs {type: 'Item', uuid: 'Item.gMEGT8uT7cFwwRbA'}
}
}
If instead, I use SvelteApplication, then the drop does not work:
import { SvelteApplication } from '@typhonjs-fvtt/runtime/svelte/application';
export default class MyActorSheet extends SvelteApplication {

static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
dragDrop: [{ dragSelector: ".directory-list .item", dropSelector: null }],
});
}

async _onDrop(event) {
const data = TextEditor.getDragEventData(event);
console.log('data: ', data); //<-- outputs {}
}
}
import { SvelteApplication } from '@typhonjs-fvtt/runtime/svelte/application';
export default class MyActorSheet extends SvelteApplication {

static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
dragDrop: [{ dragSelector: ".directory-list .item", dropSelector: null }],
});
}

async _onDrop(event) {
const data = TextEditor.getDragEventData(event);
console.log('data: ', data); //<-- outputs {}
}
}
Is it me? @mleahy Maybe I shouldn't be trying to use the native drop listener
TyphonJS (Michael)
An 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 listener
Well 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.
geoidesic
geoidesic11mo ago
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.
TyphonJS (Michael)
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.
geoidesic
geoidesic11mo ago
Doesn't my example above show that the data is correct? I'm pretty sure it does.
TyphonJS (Michael)
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/DataTransfer
geoidesic
geoidesic11mo ago
You 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 UI
Yes I am dragging from core Foundry UI
Sight unseen I gather that there isn't a proper data transfer object attached to the drop event
Correct but only for v11 using SvelteApplication
TyphonJS (Michael)
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.
geoidesic
geoidesic11mo ago
But it is defined if I use ActorSheet . If it was a configuration issue with core platform then why would that work?
geoidesic
geoidesic11mo ago
GitHub
Titan-VTTRPG/system.json at 054104f40e22fda3b84817a5d0a32aabc1b247c...
Contribute to Solidor777/Titan-VTTRPG development by creating an account on GitHub.
TyphonJS (Michael)
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.
geoidesic
geoidesic11mo ago
I assume you may have essential-svelte-esm installed. In the basic document drop example
Yes, 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
TyphonJS (Michael)
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.
geoidesic
geoidesic11mo ago
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:
export default class BasicDocumentApp extends SvelteApplication {

static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
id: 'surge-actor-sheet',
title: 'Surge Actor Sheet',
resizable: true,
template: "systems/surge/src/templates/sheets/actor-sheet.html",
width: 500,
height: 'auto',
dragDrop: [{ dragSelector: '.directory-list .item', dropSelector: '.dropper' }],
// svelte: {
// class: BasicDocAppShell,
// target: document.body,
// }
});
}

async _onDrop(event) {
const data = TextEditor.getDragEventData(event);
console.log('data', data);

}
}
export default class BasicDocumentApp extends SvelteApplication {

static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
id: 'surge-actor-sheet',
title: 'Surge Actor Sheet',
resizable: true,
template: "systems/surge/src/templates/sheets/actor-sheet.html",
width: 500,
height: 'auto',
dragDrop: [{ dragSelector: '.directory-list .item', dropSelector: '.dropper' }],
// svelte: {
// class: BasicDocAppShell,
// target: document.body,
// }
});
}

async _onDrop(event) {
const data = TextEditor.getDragEventData(event);
console.log('data', data);

}
}
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:
export default class BasicDocumentApp extends SvelteApplication {

static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
id: 'surge-actor-sheet',
title: 'Surge Actor Sheet',
resizable: true,
// template: "systems/surge/src/templates/sheets/actor-sheet.html",
width: 500,
height: 'auto',
dragDrop: [{ dragSelector: '.directory-list .item', dropSelector: '.dropper' }],
svelte: {
class: BasicDocAppShell,
target: document.body,
}
});
}

async _onDrop(event) {
const data = TextEditor.getDragEventData(event);
console.log('data', data);

}
}
export default class BasicDocumentApp extends SvelteApplication {

static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
id: 'surge-actor-sheet',
title: 'Surge Actor Sheet',
resizable: true,
// template: "systems/surge/src/templates/sheets/actor-sheet.html",
width: 500,
height: 'auto',
dragDrop: [{ dragSelector: '.directory-list .item', dropSelector: '.dropper' }],
svelte: {
class: BasicDocAppShell,
target: document.body,
}
});
}

async _onDrop(event) {
const data = TextEditor.getDragEventData(event);
console.log('data', data);

}
}
TyphonJS (Michael)
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:
/** @inheritdoc */
_canDragStart(selector) {
return this.isEditable;
}

/* -------------------------------------------- */

/** @inheritdoc */
_canDragDrop(selector) {
return this.isEditable;
}
/** @inheritdoc */
_canDragStart(selector) {
return this.isEditable;
}

/* -------------------------------------------- */

/** @inheritdoc */
_canDragDrop(selector) {
return this.isEditable;
}
Otherwise by default only the GM can drag and drop.
geoidesic
geoidesic11mo ago
But it seems to me that you're not understanding that it is working, as long as I don't use the svelte template.
TyphonJS (Michael)
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.
geoidesic
geoidesic11mo ago
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.
TyphonJS (Michael)
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.
geoidesic
geoidesic11mo ago
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.
TyphonJS (Michael)
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:
const el = html[0];
const el = html[0];
In v11 it does this:
const content = this.popOut ? html[0].parentElement : html[0];
const content = this.popOut ? html[0].parentElement : html[0];
Full v11 method:
/**
* Activate required listeners which must be enabled on every Application.
* These are internal interactions which should not be overridden by downstream subclasses.
* @param {jQuery} html
* @protected
*/
_activateCoreListeners(html) {
const content = this.popOut ? html[0].parentElement : html[0];

this._tabs.forEach(t => t.bind(content));
this._dragDrop.forEach(d => d.bind(content));
this._searchFilters.forEach(f => f.bind(content));
}
/**
* Activate required listeners which must be enabled on every Application.
* These are internal interactions which should not be overridden by downstream subclasses.
* @param {jQuery} html
* @protected
*/
_activateCoreListeners(html) {
const content = this.popOut ? html[0].parentElement : html[0];

this._tabs.forEach(t => t.bind(content));
this._dragDrop.forEach(d => d.bind(content));
this._searchFilters.forEach(f => f.bind(content));
}
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.
geoidesic
geoidesic11mo ago
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 actually
TyphonJS (Michael)
I'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.
geoidesic
geoidesic11mo ago
Time for me to hit the sack... tx again for the feedback
Solidor
Solidor11mo ago
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
geoidesic
geoidesic11mo ago
@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.
TyphonJS (Michael)
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:
super._activateCoreListeners(typeof this.options.template === 'string' ? html :
[this.popOut ? this.#elementTarget?.firstChild : this.#elementTarget]);
super._activateCoreListeners(typeof this.options.template === 'string' ? html :
[this.popOut ? this.#elementTarget?.firstChild : this.#elementTarget]);
line 996 to:
super._activateCoreListeners([this.popOut ? this.#elementTarget?.firstChild : this.#elementTarget]);
super._activateCoreListeners([this.popOut ? this.#elementTarget?.firstChild : this.#elementTarget]);
Theses changes take into account the underlying changes in Application._activateCoreListeners.
Solidor
Solidor11mo ago
Gotcha
Nekro Darkmoon
Nekro Darkmoon11mo ago
.
TyphonJS (Michael)
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.
Solidor
Solidor11mo ago
I can test that out later today!
TyphonJS (Michael)
--- 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.
Solidor
Solidor11mo ago
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
TyphonJS (Michael)
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.
Solidor
Solidor11mo ago
@mleahy The change seems to work for me!
TyphonJS (Michael)
Awesome... Yeah.. will lose v10 support, but I think the core drag and drop is only being used by system devs currently.
Solidor
Solidor11mo ago
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?
TyphonJS (Michael)
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.
TyphonJS (Michael)
I don't think it's a problem, but testing is always good... Here is the _activateCoreListeners method again:
_activateCoreListeners(html) {
const content = this.popOut ? html[0].parentElement : html[0];
this._tabs.forEach(t => t.bind(content));
this._dragDrop.forEach(d => d.bind(content));
this._searchFilters.forEach(f => f.bind(content));
}
_activateCoreListeners(html) {
const content = this.popOut ? html[0].parentElement : html[0];
this._tabs.forEach(t => t.bind(content));
this._dragDrop.forEach(d => d.bind(content));
this._searchFilters.forEach(f => f.bind(content));
}
And the DragDrop.bind method (IE it should only be targeting the app div passed in which is html):
bind(html) {

// Identify and activate draggable targets
if ( this.can("dragstart", this.dragSelector) ) {
const draggables = html.querySelectorAll(this.dragSelector);
for (let el of draggables) {
el.setAttribute("draggable", true);
el.ondragstart = this._handleDragStart.bind(this);
}
}

// Identify and activate drop targets
if ( this.can("drop", this.dropSelector) ) {
const droppables = !this.dropSelector || html.matches(this.dropSelector) ? [html] :
html.querySelectorAll(this.dropSelector);
for ( let el of droppables ) {
el.ondragover = this._handleDragOver.bind(this);
el.ondrop = this._handleDrop.bind(this);
}
}
return this;
}
bind(html) {

// Identify and activate draggable targets
if ( this.can("dragstart", this.dragSelector) ) {
const draggables = html.querySelectorAll(this.dragSelector);
for (let el of draggables) {
el.setAttribute("draggable", true);
el.ondragstart = this._handleDragStart.bind(this);
}
}

// Identify and activate drop targets
if ( this.can("drop", this.dropSelector) ) {
const droppables = !this.dropSelector || html.matches(this.dropSelector) ? [html] :
html.querySelectorAll(this.dropSelector);
for ( let el of droppables ) {
el.ondragover = this._handleDragOver.bind(this);
el.ondrop = this._handleDrop.bind(this);
}
}
return this;
}
Solidor
Solidor11mo ago
Thank you both
Nekro Darkmoon
Nekro Darkmoon11mo ago
Our system is quite close to being ready for 1.0.0
TyphonJS (Michael)
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.
Nekro Darkmoon
Nekro Darkmoon11mo ago
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 🤣
TyphonJS (Michael)
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.
Nekro Darkmoon
Nekro Darkmoon11mo ago
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
TyphonJS (Michael)
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.
Nekro Darkmoon
Nekro Darkmoon11mo ago
focus handling has always been a pain the core way to sort stuff is also a major pain
TyphonJS (Michael)
UI / UX is not a strong point of the Foundry team as things go.
Nekro Darkmoon
Nekro Darkmoon11mo ago
😄 They've hired a ux/ui designer recently
TyphonJS (Michael)
canvas and all the pixi stuff... not bad... not bad.. so I will throw a bone out there.
Nekro Darkmoon
Nekro Darkmoon11mo ago
so hopefully things will start imporving
TyphonJS (Michael)
It's the programming / implementation side that needs tons of help. I have my fingers crossed that "App v2" is not a homespun framework.
Nekro Darkmoon
Nekro Darkmoon11mo ago
😄 I'll move into #dev-lounge
TyphonJS (Michael)
Yeah.. Easy to derail... 😄
geoidesic
geoidesic11mo ago
For me SvelteApplication doesn't have a line 996, only goes to line 991. From package.json:
{
"name": "@typhonjs-fvtt/runtime",
"version": "0.0.23",
{
"name": "@typhonjs-fvtt/runtime",
"version": "0.0.23",
TyphonJS (Michael)
https://github.com/typhonjs-fvtt-lib/svelte/blob/main/src/application/SvelteApplication.js#L220
super._activateCoreListeners(typeof this.options.template === 'string' ? html :
[this.popOut ? this.#elementTarget?.firstChild : this.#elementTarget]);
super._activateCoreListeners(typeof this.options.template === 'string' ? html :
[this.popOut ? this.#elementTarget?.firstChild : this.#elementTarget]);
https://github.com/typhonjs-fvtt-lib/svelte/blob/main/src/application/SvelteApplication.js#L974
super._activateCoreListeners([this.popOut ? this.#elementTarget?.firstChild : this.#elementTarget]);
super._activateCoreListeners([this.popOut ? this.#elementTarget?.firstChild : this.#elementTarget]);
geoidesic
geoidesic11mo ago
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.
TyphonJS (Michael)
If you are running Vite in dev mode it caches the build. Try a production build.
geoidesic
geoidesic11mo ago
Thanks. I wasn't aware of the .vite-cache . Good to know. Yes, I can confirm this patch works!
TyphonJS (Michael)
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.
geoidesic
geoidesic11mo ago
As mentioned though this change will make things stop working on v10 probably
Yep, and anyone who needs both (for whatever reason) can just add a version conditional in. All good.
TyphonJS (Michael)
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.
geoidesic
geoidesic11mo ago
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.
TyphonJS (Michael)
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.
geoidesic
geoidesic11mo ago
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
TyphonJS (Michael)
No the manual patch described above in this thread specifically for connecting the core event handlers on v11.
geoidesic
geoidesic11mo ago
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:
1:55:38 AM [vite] Internal server error: Missing "./svelte/store" specifier in "@typhonjs-fvtt/runtime" package
Plugin: vite:import-analysis
1:55:38 AM [vite] Internal server error: Missing "./svelte/store" specifier in "@typhonjs-fvtt/runtime" package
Plugin: vite:import-analysis
Which are related to these imports methinks:
import { SvelteApplication } from "@typhonjs-fvtt/runtime/svelte/application";
import { TJSDocument } from "@typhonjs-fvtt/runtime/svelte/store";
import { SvelteApplication } from "@typhonjs-fvtt/runtime/svelte/application";
import { TJSDocument } from "@typhonjs-fvtt/runtime/svelte/store";
TyphonJS (Michael)
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.
geoidesic
geoidesic11mo ago
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.
TyphonJS (Michael)
If you searched the API docs you'd quickly find the new ripple effect import location:
No description
TyphonJS (Michael)
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.
geoidesic
geoidesic11mo ago
I usually get that when an import is wrong. Although no build nor console errors now, so will have to divide and conquer it.
TyphonJS (Michael)
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.
geoidesic
geoidesic11mo ago
hmm. debounce seems problematic
TyphonJS (Michael)
Yes.. You can watch the video overview when I walked through the changes necessary... If you searched the API docs though.. guess what..
import { Timing } from '@typhonjs-fvtt/runtime/util';

Timing.debounce(() => ....);
import { Timing } from '@typhonjs-fvtt/runtime/util';

Timing.debounce(() => ....);
No description
TyphonJS (Michael)
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.
geoidesic
geoidesic11mo ago
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:
Uncaught (in promise) TypeError: undefined. EmbeddedStoreManager.create error: 'FoundryDoc' does not have a valid 'documentName' property.
Uncaught (in promise) TypeError: undefined. EmbeddedStoreManager.create error: 'FoundryDoc' does not have a valid 'documentName' property.
TyphonJS (Michael)
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#create
geoidesic
geoidesic11mo ago
Ok 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! 👏🏻