Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions nicegui/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@
from .awaitable_response import AwaitableResponse
from .dependencies import generate_resources
from .element import Element

# HACK: Hoist all importmap-based elements here to fix lazy import
from .elements.aggrid.aggrid import AgGrid # noqa: F401 # pylint: disable=unused-import
from .elements.codemirror.codemirror import CodeMirror # noqa: F401 # pylint: disable=unused-import
from .elements.echart.echart import EChart # noqa: F401 # pylint: disable=unused-import
from .elements.joystick.joystick import Joystick # noqa: F401 # pylint: disable=unused-import
from .elements.json_editor.json_editor import JsonEditor # noqa: F401 # pylint: disable=unused-import
from .elements.leaflet.leaflet import Leaflet # noqa: F401 # pylint: disable=unused-import
from .elements.mermaid.mermaid import Mermaid # noqa: F401 # pylint: disable=unused-import
from .elements.plotly.plotly import Plotly # noqa: F401 # pylint: disable=unused-import
from .elements.scene.scene import Scene # noqa: F401 # pylint: disable=unused-import
from .elements.xterm.xterm import Xterm # noqa: F401 # pylint: disable=unused-import
from .favicon import get_favicon_url
from .javascript_request import JavaScriptRequest
from .logging import log
Expand Down
108 changes: 56 additions & 52 deletions nicegui/functions/clipboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,65 +12,69 @@
pass


async def read() -> Optional[str]:
"""Read text from the clipboard.
class Clipboard:
"""Wrapper for clipboard helper functions."""

Note: This function only works in secure contexts (HTTPS or localhost).
"""
result = await run_javascript('''
if (navigator.clipboard) {
return navigator.clipboard.readText()
}
else {
console.error('Clipboard API is only available in secure contexts (HTTPS or localhost).')
}
''')
if result is None:
log.warning('Clipboard API is only available in secure contexts (HTTPS or localhost).')
return result
async def read(self) -> Optional[str]:
"""Read text from the clipboard.

Note: This function only works in secure contexts (HTTPS or localhost).
"""
result = await run_javascript('''
if (navigator.clipboard) {
return navigator.clipboard.readText()
}
else {
console.error('Clipboard API is only available in secure contexts (HTTPS or localhost).')
}
''')
if result is None:
log.warning('Clipboard API is only available in secure contexts (HTTPS or localhost).')
return result

def write(text: str) -> None:
"""Write text to the clipboard.

Note: This function only works in secure contexts (HTTPS or localhost).
def write(self, text: str) -> None:
"""Write text to the clipboard.

:param text: text to write
"""
run_javascript(f'''
if (navigator.clipboard) {{
navigator.clipboard.writeText({json.dumps(text)})
}}
else {{
console.error('Clipboard API is only available in secure contexts (HTTPS or localhost).')
}}
''')
Note: This function only works in secure contexts (HTTPS or localhost).

:param text: text to write
"""
run_javascript(f'''
if (navigator.clipboard) {{
navigator.clipboard.writeText({json.dumps(text)})
}}
else {{
console.error('Clipboard API is only available in secure contexts (HTTPS or localhost).')
}}
''')

async def read_image() -> Union['PIL_Image.Image', None]:
"""Read PIL images from the clipboard.
async def read_image(self) -> Union['PIL_Image.Image', None]:
"""Read PIL images from the clipboard.

Note: This function only works in secure contexts (HTTPS or localhost) and requires Pillow to be installed.
Note: This function only works in secure contexts (HTTPS or localhost) and requires Pillow to be installed.

*Added in version 2.10.0*
"""
if not optional_features.has('pillow'):
log.warning('Pillow is not installed, so we cannot read images from the clipboard.')
return None
content = await run_javascript('''
if (navigator.clipboard) {
const items = await navigator.clipboard.read();
for (const item of items) {
if (item.types.length > 0 && /^image/.test(item.types[0])) {
return await item.getType(item.types[0]);
*Added in version 2.10.0*
"""
if not optional_features.has('pillow'):
log.warning('Pillow is not installed, so we cannot read images from the clipboard.')
return None
content = await run_javascript('''
if (navigator.clipboard) {
const items = await navigator.clipboard.read();
for (const item of items) {
if (item.types.length > 0 && /^image/.test(item.types[0])) {
return await item.getType(item.types[0]);
}
}
}
}
else {
console.error('Clipboard API is only available in secure contexts (HTTPS or localhost).');
}
''', timeout=5)
if not content:
return None
buffer = io.BytesIO(content)
return PIL_Image.open(buffer)
else {
console.error('Clipboard API is only available in secure contexts (HTTPS or localhost).');
}
''', timeout=5)
if not content:
return None
buffer = io.BytesIO(content)
return PIL_Image.open(buffer)


clipboard = Clipboard()
Loading