r0x0r/pywebview

How do I get the dropped path in JavaScript?

chdominguez opened this issue · 4 comments

Specification

  • pywebview version: 5.0.5
  • operating system: macOS 13
  • web renderer: Cocoa

Description

I have been looking to the documentation and I can get the full path of a dropped file in python. My question is if there is an easy way of obtaining the full path of that file directly in JavaScript, as I need the path to be displayed on the frontend.

Practicalities

  • YES I am willing to work on this issue myself.

  • NO I am prepared to support this issue financially.

You cannot get it directly in Javascript as it would violate browser's security constraints, but you can obtain it in Python and pass back to Javascript from Python.

Thanks for your answer. I know about browser's security constraints, my question was more related to how to pass back the information from python into the frontend. I could use some WebSocket connection but I think it will be overkill for only getting a path. Do you know if there's an easier way? I was thinking maybe into evaluating a JS snippet that fires an event to the window from the python side.

A naïve straightforward solution would be execute window.evaluate_js() that would set file path to some object inside the drop event handler in Python and set an interval in Javascript that would poll for this value.

I made it work using a very straightforward method using the evaluate_js function. I'll leave the code here in case its useful for someone in the future as a reference.

import webview
from webview.dom import DOMEventHandler
from webview.window import Window


def fire_full_path_event(path: str) -> str:

    return f"""
    const event = new CustomEvent("pywebviewDrop", {{
      detail: {{ 
        pywebviewFullPath: "{path}"}},
    }});

    window.dispatchEvent(event);
    """


def on_drop(e, w: Window):
    files = e["dataTransfer"]["files"]
    if len(files) == 0:
        return

    for file in files:
        filePath = file.get("pywebviewFullPath")
        if filePath:
            w.evaluate_js(fire_full_path_event(filePath))


def bind(window):
    window.dom.document.events.drop += DOMEventHandler(
        lambda e: on_drop(e, window), True, True
    )


if __name__ == "__main__":
    window = webview.create_window(
        "Drag & drop example",
        html="""
            <html>
                <head>
                    <script>
                        window.addEventListener("pywebviewDrop", (e) => {
                            console.log(e.detail.pywebviewFullPath);
                        })
                    </script>
                </head>
                <body style="height: 100vh;"->
                    <h1>Drag files here</h1>
                </body>
            </html>
        """,
    )
    webview.start(bind, [window], debug=True)