Skip to content

Expose webUtils.getPathForFile as window.Native.getPathForFile for dropped files - #170

Open
PunchRockgroin wants to merge 1 commit into
NativePHP:mainfrom
PunchRockgroin:feature/native-get-path-for-file
Open

PunchRockgroin wants to merge 1 commit into
NativePHP:mainfrom
PunchRockgroin:feature/native-get-path-for-file

Conversation

@PunchRockgroin

Copy link
Copy Markdown

What this does

Adds getPathForFile(file) to the window.Native object the preload exposes. It returns the file system path of a File from a drag-and-drop or an <input type="file">.

window.addEventListener('drop', (e) => {
    e.preventDefault();

    const paths = [...e.dataTransfer.files].map((file) => window.Native.getPathForFile(file));
});

Why

Electron 32 removed the non-standard File.path and replaced it with webUtils.getPathForFile(). That function can only be called from a preload script.

A NativePHP app can't currently get the path of a file a user drags into a window:

  • The renderer runs with contextIsolation: true and nodeIntegration: false, so the page has no access to webUtils.
  • webPreferences.preload is a required preference, so an app can't add its own preload alongside NativePHP's.

Desktop apps commonly need the original path rather than an upload of the contents. Examples include working with the file where it is, watching it, checking whether another program has it open, or handling large files without copying them through a request.

Notes

  • This follows Electron's own recommended pattern (Native File Drag & Drop). It only resolves File objects the user has dropped or picked, so it doesn't let the page read arbitrary paths.
  • getPathForFile returns an empty string for a File that isn't backed by a file on disk, such as one built in JavaScript.
  • An image dragged from a web browser depends on the browser, before getPathForFile is involved. Firefox saves a temporary copy (for example C:\Users\<user>\AppData\Local\Temp\image.jpg on Windows) and that's the path returned. Chrome on Windows gives a File with no file on disk behind it, so getPathForFile returns ''. Chrome on macOS gives a drop with no files at all.
  • dist/preload/index.mjs is updated to match. It's what npm run plugin:build (tsc) emits for the source change.
  • The method is added to the existing Native object, so window.Native.on() and window.Native.contextMenu() are unchanged.

Testing

Tested with php artisan native:run and a page that listens for drop, on Windows 11 and on macOS Tahoe 26.6 (M5 MacBook Pro). Thanks to @lexchristopher03 for the macOS testing.

  • npm run plugin:build in resources/electron gives the same dist/preload/index.mjs as in this PR
  • Dropping a file from Explorer / Finder gives its full path (Windows, macOS)
  • Dropping several files at once gives each one's path (macOS)
  • A file picked with <input type="file"> gives its full path (macOS)
  • A file on a UNC path (\\server\share\...) gives its path (Windows). Not tried on a macOS network share.
  • An image dragged from Firefox gives the path of Firefox's temporary copy (Windows, macOS)
  • An image dragged from Chrome gives '' on Windows, and a drop with no files on macOS
  • A File built in JavaScript gives '' (Windows, macOS)
  • Linux (not tested)

Docs

I have a matching docs addition for resources/views/docs/desktop/2/digging-deeper/files.md in NativePHP/nativephp.com, and I'm happy to open it as a separate PR there.

…opped files

Electron 32 removed File.path in favour of webUtils.getPathForFile(), which
is only available in a preload script. With contextIsolation enabled and
NativePHP's preload always set, apps had no way to get the path of a file
dropped into a window or picked with <input type="file">.
@lexchristopher03

Copy link
Copy Markdown

Tested on an M5 MacBook Pro, macOS Tahoe 26.6, with php artisan native:run:

Dropping a single file from Finder: full path, e.g. /Users/lexie/Desktop/NativePHPTestFile.jpeg
Dropping three files at once: each file's full path
File picker (): full path
A File built in JavaScript: ''
An image dragged from Firefox: path of Firefox's temporary copy
An image dragged from Chrome: the drop has no files

Didn't try a network share.

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

Successfully merging this pull request may close these issues.

2 participants