def __init__(self, elt_id=None, globals=None, locals=None): if elt_id is None: d = Dialog("REPL") self.zone = html.TEXTAREA(rows=30, cols=60) d.panel <= self.zone else: self.zone = document[elt_id] v = sys.implementation.version self.zone.value = "Brython %s.%s.%s on %s %s\n>>> " % ( v[0], v[1], v[2], window.navigator.appName, window.navigator.appVersion) self.zone.focus() self.cursorToEnd() self._status = "main" self.current = 0 self.history = [] self.buffer = '' sys.stdout.write = sys.stderr.write = self.write sys.stdout.__len__ = sys.stderr.__len__ = lambda: len(self.buffer) self.globals = globals or {} self.globals.update(editor_ns) self.locals = locals or {} self.zone.bind('keypress', self.myKeyPress) self.zone.bind('keydown', self.myKeyDown) self.zone.bind('click', self.cursorToEnd)
def vfs_open(evt): """Search all file names in the indexedDB database, open a dialog window to select a file to open.""" db = request.result tx = db.transaction("scripts", "readonly") store = tx.objectStore("scripts") cursor = store.openCursor() dialog_window = Dialog("Open file...", top=filebrowser.abs_top, left=filebrowser.abs_left) scripts = [] script_style = {"cursor": "default"} def get_scripts(evt): res = evt.target.result if res: scripts.append(res.value.name) getattr(res, "continue")() else: scripts.sort() for script in scripts: script_elt = html.SPAN(script, style=script_style) dialog_window.panel <= script_elt + html.BR() script_elt.bind("click", open_script) cursor.bind('success', get_scripts)
def show_finished(): #InfoDialog("Congratulations!", "You found all the words") d = Dialog("Test", ok_cancel=False) d.panel <= stars.finished("popupfinished") """
def test_browser_widgets_dialog(): from browser.widgets.dialog import InfoDialog # Info box with customized "Ok" button d1 = InfoDialog("Test", "Information message", ok="Got it") from browser.widgets.dialog import InfoDialog # Info box that disappears after 3 seconds d1 = InfoDialog("Test", "Closing in 3 seconds", remove_after=3) from browser import bind from browser.widgets.dialog import InfoDialog, EntryDialog d = EntryDialog("Test", "Name") @bind(d, "entry") def entry(ev): value = d.value d.close() InfoDialog("Test", f"Hello, {value} !") ## added entry(evt) from browser import bind, html from browser.widgets.dialog import Dialog, EntryDialog, InfoDialog translations = {'Français': 'Salut', 'Español': 'Hola', 'Italiano': 'Ciao'} d = Dialog("Test", ok_cancel=True) style = dict(textAlign="center", paddingBottom="1em") d.panel <= html.DIV("Name " + html.INPUT(), style=style) d.panel <= html.DIV( "Language " + html.SELECT(html.OPTION(k) for k in translations), style=style) # Event handler for "Ok" button @bind(d.ok_button, "click") def ok(ev): """InfoDialog with text depending on user entry, at the same position as the original box.""" language = d.select_one("SELECT").value prompt = translations[language] name = d.select_one("INPUT").value left, top = d.scrolled_left, d.scrolled_top d.close() d3 = InfoDialog("Test", f"{prompt}, {name} !", left=left, top=top) ## added translations[0] = "test" # mockbrython hashes to 0, avoid KeyError ok(evt)
def __init__(self, elt_id=None, title="REPL", globals=None, locals=None): """ Create the interpreter. - "elt_id" is the id of a textarea in the document. If not set, a new popup window is added with a textarea. - "globals" and "locals" are the namespaces the RPEL runs in """ if elt_id is None: self.dialog = Dialog(title=title, top=10, left=10) self.zone = html.TEXTAREA(rows=30, cols=60) set_style(self.zone, "brython-console") self.dialog.panel <= self.zone else: self.zone = document[elt_id] v = sys.implementation.version self.zone.value = (f"Brython {v[0]}.{v[1]}.{v[2]} on " + f"{window.navigator.appName} {window.navigator.appVersion}\n>>> ") self.zone.focus() self.cursor_to_end() self._status = "main" self.current = 0 self.history = [] self.globals = {} if globals is None else globals self.globals.update(editor_ns) self.locals = {} if locals is None else locals self.buffer = '' sys.stdout.write = sys.stderr.write = self.write sys.stdout.__len__ = sys.stderr.__len__ = lambda: len(self.buffer) self.zone.bind('keypress', self.keypress) self.zone.bind('keydown', self.keydown) self.zone.bind('mouseup', self.mouseup) self.zone.focus()
def __init__(self, elt_id=None, title="Interactive Interpreter", globals=None, locals=None, history=None, rows=30, cols=84, default_css=True, clear_zone=True, banner=True): """ Create the interpreter. - "elt_id" is the id of a textarea in the document. If not set, a new popup window is added with a textarea. - "globals" and "locals" are the namespaces the RPEL runs in - "history", if set, must be a list of strings """ if default_css: # Insert default CSS stylesheet if not already loaded for stylesheet in document.styleSheets: if stylesheet.ownerNode.id == "brython-interpreter": break else: document <= html.STYLE(style_sheet, id="brython-interpreter") if elt_id is None: self.dialog = Dialog(title=title, top=10, left=10, default_css=default_css) self.zone = html.TEXTAREA(rows=rows, cols=cols, Class="brython-interpreter") self.dialog.panel <= self.zone else: if isinstance(elt_id, str): try: elt = document[elt_id] if elt.tagName != "TEXTAREA": raise ValueError( f"element {elt_id} is a {elt.tagName}, " + "not a TEXTAREA") self.zone = elt except KeyError: raise KeyError(f"no element with id '{elt_id}'") elif isinstance(elt_id, DOMNode): if elt_id.tagName == "TEXTAREA": self.zone = elt_id else: raise ValueError("element is not a TEXTAREA") else: raise ValueError( "element should be a string or " + f"a TEXTAREA, got '{elt_id.__class__.__name__}'") v = sys.implementation.version if clear_zone: self.zone.value = '' if banner: self.zone.value += ( f"Brython {v[0]}.{v[1]}.{v[2]} on " f"{window.navigator.appName} {window.navigator.appVersion}" "\n") self.zone.value += ">>> " self.cursor_to_end() self._status = "main" self.history = history or [] self.current = len(self.history) self.globals = {} if globals is None else globals self.globals.update(editor_ns) self.locals = self.globals if locals is None else locals self.buffer = '' sys.stdout.write = sys.stderr.write = self.write sys.stdout.__len__ = sys.stderr.__len__ = lambda: len(self.buffer) self.zone.bind('keypress', self.keypress) self.zone.bind('keydown', self.keydown) self.zone.bind('mouseup', self.mouseup) self.zone.focus()
class Interpreter: """Add a Python interactive interpreter in a textarea.""" def __init__(self, elt_id=None, title="Interactive Interpreter", globals=None, locals=None, history=None, rows=30, cols=84, default_css=True, clear_zone=True, banner=True): """ Create the interpreter. - "elt_id" is the id of a textarea in the document. If not set, a new popup window is added with a textarea. - "globals" and "locals" are the namespaces the RPEL runs in - "history", if set, must be a list of strings """ if default_css: # Insert default CSS stylesheet if not already loaded for stylesheet in document.styleSheets: if stylesheet.ownerNode.id == "brython-interpreter": break else: document <= html.STYLE(style_sheet, id="brython-interpreter") if elt_id is None: self.dialog = Dialog(title=title, top=10, left=10, default_css=default_css) self.dialog.bind('blur', self.blur) self.dialog.bind('click', self.focus) self.dialog.close_button.bind('click', self.close) self.zone = html.TEXTAREA(rows=rows, cols=cols, Class="brython-interpreter") self.dialog.panel <= self.zone else: if isinstance(elt_id, str): try: elt = document[elt_id] if elt.tagName != "TEXTAREA": raise ValueError( f"element {elt_id} is a {elt.tagName}, " + "not a TEXTAREA") self.zone = elt except KeyError: raise KeyError(f"no element with id '{elt_id}'") elif isinstance(elt_id, DOMNode): if elt_id.tagName == "TEXTAREA": self.zone = elt_id else: raise ValueError("element is not a TEXTAREA") else: raise ValueError( "element should be a string or " + f"a TEXTAREA, got '{elt_id.__class__.__name__}'") v = sys.implementation.version if clear_zone: self.zone.value = '' if banner: self.zone.value += ( f"Brython {v[0]}.{v[1]}.{v[2]} on " f"{window.navigator.appName} {window.navigator.appVersion}" "\n") self.zone.value += ">>> " self.cursor_to_end() self._status = "main" self.history = history or [] self.current = len(self.history) self.globals = {} if globals is None else globals self.globals.update(editor_ns) self.locals = self.globals if locals is None else locals self.buffer = '' self.zone.bind('keypress', self.keypress) self.zone.bind('keydown', self.keydown) self.zone.bind('mouseup', self.mouseup) self.zone.bind('focus', self.focus) self.zone.bind('blur', self.blur) self.zone.focus() active.append(self) def blur(self, ev): if hasattr(self, 'dialog'): self.dialog.style.zIndex = 0 def close(self, ev): active.remove(self) def cursor_to_end(self, *args): pos = len(self.zone.value) self.zone.setSelectionRange(pos, pos) self.zone.scrollTop = self.zone.scrollHeight def focus(self, *args): """When the interpreter gets focus, set sys.stdout and stderr""" if hasattr(self, 'dialog'): # put other active windows in the background for w in active: if w is not self: w.dialog.style.zIndex = 0 self.dialog.style.zIndex = 1 sys.stdout = sys.stderr = Output(self) self.zone.focus() def get_col(self): # returns the column num of cursor sel = self.zone.selectionStart lines = self.zone.value.split('\n') for line in lines[:-1]: sel -= len(line) + 1 return sel def keypress(self, event): if event.key == "Tab": # tab key event.preventDefault() self.zone.value += " " elif event.key == "Enter": # return sel_start = self.zone.selectionStart sel_end = self.zone.selectionEnd if sel_end > sel_start: # If text was selected by the mouse, copy to clipboard document.execCommand("copy") self.cursor_to_end() event.preventDefault() # don't insert line feed return src = self.zone.value self.handle_line(self, event) def feed(self, src): """src is Python source code, possibly on several lines. Simulate typing the code in the interpreter. Can be used for debugging, or showing how a code snippet executes. """ current_indent = 0 for line in src.split('\n'): mo = re.match('^\s*', line) indent = mo.end() - mo.start() current_indent = indent self.zone.value += line self.handle_line(line) def handle_line(self, code, event=None): src = self.zone.value if self._status == "main": currentLine = src[src.rfind('\n>>>') + 5:] elif self._status == "3string": currentLine = src[src.rfind('\n>>>') + 5:] currentLine = currentLine.replace('\n... ', '\n') else: currentLine = src[src.rfind('\n...') + 5:] if self._status == 'main' and not currentLine.strip(): self.zone.value += '\n>>> ' if event is not None: event.preventDefault() return self.zone.value += '\n' self.history.append(currentLine) self.current = len(self.history) if self._status in ["main", "3string"]: try: _ = self.globals['_'] = eval(currentLine, self.globals, self.locals) if _ is not None: self.write(repr(_) + '\n') self.flush() self.zone.value += '>>> ' self._status = "main" except IndentationError: self.zone.value += '... ' self._status = "block" except SyntaxError as msg: if str(msg).startswith( 'unterminated triple-quoted string literal'): self.zone.value += '... ' self._status = "3string" elif str(msg) == 'decorator expects function': self.zone.value += '... ' self._status = "block" elif str(msg).endswith('was never closed'): self.zone.value += '... ' self._status = "block" else: try: exec(currentLine, self.globals, self.locals) except: self.print_tb() #self.syntax_error(msg.args) self.zone.value += '>>> ' self._status = "main" except: # the full traceback includes the call to eval(); to # remove it, it is stored in a buffer and the 2nd and 3rd # lines are removed self.print_tb() self.zone.value += '>>> ' self._status = "main" elif currentLine == "": # end of block block = src[src.rfind('\n>>>') + 5:].splitlines() block = [block[0]] + [b[4:] for b in block[1:]] block_src = '\n'.join(block) # status must be set before executing code in globals() self._status = "main" try: _ = exec(block_src, self.globals, self.locals) if _ is not None: print(repr(_)) except: self.print_tb() self.flush() self.zone.value += '>>> ' else: self.zone.value += '... ' self.cursor_to_end() if event is not None: event.preventDefault() def keydown(self, event): if event.key == "ArrowLeft": sel = self.get_col() if sel < 5: event.preventDefault() event.stopPropagation() elif event.key == "Home": pos = self.zone.selectionStart col = self.get_col() self.zone.setSelectionRange(pos - col + 4, pos - col + 4) event.preventDefault() elif event.key == "ArrowUp": if self.current > 0: pos = self.zone.selectionStart col = self.get_col() # remove current line self.zone.value = self.zone.value[:pos - col + 4] self.current -= 1 self.zone.value += self.history[self.current] event.preventDefault() elif event.key == "ArrowDown": if self.current < len(self.history) - 1: pos = self.zone.selectionStart col = self.get_col() # remove current line self.zone.value = self.zone.value[:pos - col + 4] self.current += 1 self.zone.value += self.history[self.current] event.preventDefault() elif event.key == "Backspace": src = self.zone.value lstart = src.rfind('\n') if (lstart == -1 and len(src) < 5) or (len(src) - lstart < 6): event.preventDefault() event.stopPropagation() elif event.key in ["PageUp", "PageDown"]: event.preventDefault() def mouseup(self, ev): """If nothing was selected by the mouse, set cursor to prompt.""" sel_start = self.zone.selectionStart sel_end = self.zone.selectionEnd if sel_end == sel_start: self.cursor_to_end() def write(self, data): self.buffer += str(data) def flush(self): self.zone.value += self.buffer self.buffer = '' def print_tb(self): trace = Trace() traceback.print_exc(file=trace) self.write(trace.format()) self.flush() def syntax_error(self, args): info, [filename, lineno, offset, line] = args print(f" File {filename}, line {lineno}") print(" " + line.rstrip()) print(" " + offset * " " + "^") print("SyntaxError:", info) self.flush()