Example #1
0
    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)
Example #2
0
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)
Example #3
0
def show_finished():
    #InfoDialog("Congratulations!", "You found all the words")

    d = Dialog("Test", ok_cancel=False)

    d.panel <= stars.finished("popupfinished")
    """
Example #4
0
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)
Example #5
0
File: repl.py Project: x00b/brython
    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()
Example #6
0
    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()
Example #7
0
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()