diff --git a/nicegui/elements/log.js b/nicegui/elements/log.js
index b4fce92ec..c171d1781 100644
--- a/nicegui/elements/log.js
+++ b/nicegui/elements/log.js
@@ -1,13 +1,25 @@
+var num_lines = 0;
+
Vue.component("log", {
- template: ``,
+ template: ``,
mounted() {
comp_dict[this.$props.jp_props.id] = this;
},
methods: {
push(line) {
+ const decoded = decodeURI(line);
const textarea = document.getElementById(this.$props.jp_props.id);
- textarea.innerHTML += (textarea.innerHTML ? "\n" : "") + line;
+ textarea.innerHTML += (num_lines ? "\n" : "") + decoded;
textarea.scrollTop = textarea.scrollHeight;
+ num_lines += decoded.split("\n").length;
+
+ const max_lines = this.$props.jp_props.options.max_lines;
+ while (max_lines != null && num_lines > max_lines) {
+ const index = textarea.innerHTML.indexOf("\n");
+ if (index == -1) break;
+ textarea.innerHTML = textarea.innerHTML.slice(index + 1);
+ num_lines -= 1;
+ }
},
},
props: {
diff --git a/nicegui/elements/log.py b/nicegui/elements/log.py
index b909709dd..c39b53cd7 100644
--- a/nicegui/elements/log.py
+++ b/nicegui/elements/log.py
@@ -1,30 +1,33 @@
import asyncio
+import urllib
from justpy.htmlcomponents import WebPage
from .custom_view import CustomView
from .element import Element
class LogView(CustomView):
- def __init__(self):
+ def __init__(self, max_lines: int):
- super().__init__('log', __file__)
+ super().__init__('log', __file__, max_lines=max_lines)
class Log(Element):
- def __init__(self):
+ def __init__(self, max_lines: int = None):
"""Log view
Create a log view that allows to add new lines without re-transmitting the whole history to the client.
+
+ :param max_lines: maximum number of lines before dropping oldest ones (default: None)
"""
- super().__init__(LogView())
+ super().__init__(LogView(max_lines=max_lines))
- self.classes('border whitespace-pre font-mono')
+ self.classes('border whitespace-pre font-mono').style('opacity: 1 !important')
async def push_async(self, line: str):
await asyncio.gather(*[
- self.view.run_method(f'push("{line}")', socket)
+ self.view.run_method(f'push("{urllib.parse.quote(line)}")', socket)
for socket in WebPage.sockets[Element.wp.page_id].values()
])