Introduction

Installation

Limitations of the "file" protocol

Frequently asked questions

Syntax, keywords and built-in functions

Standard distribution

import implementation

Brython packages

Browser interface

Introduction - DOM API
Creating a document
Accessing elements
Attributes, properties and methods

Events
Mouse events
Keyboard events
Focus events
Drag events

Query string

Interactions with Javascript

Brython-specific built-in modules

browser
browser.aio
browser.ajax
browser.html
browser.local_storage
browser.markdown
browser.object_storage
browser.session_storage
browser.svg
browser.template
browser.timer
browser.webcomponent
browser.websocket
browser.worker

Widgets
browser.widgets.dialog
browser.widgets.menu

interpreter
javascript

Working with Brython

Execution options
Testing and debugging
Deploying an application

Cookbook

Hello world !
Insert content in an element
HTML markup (bold,italic...)
HTML table
Bind and unbind events
Handle options in a SELECT
Drag and drop
Get the content of an element
Read the content of a file
Store objects locally
Example of onmouseover
 

The module browser.webcomponent is used to create custom HTML tags, using the standard DOM WebComponent technology.

A custom element can be used in the HTML page as

<popup-window>Hello !</popup-window>

The module exposes the following functions

define(tag_name, component_class[, options])

tag_name is the name of the custom tag name. The Web Component specification mandates that the tag name includes a dash (the "-" character).

component_class is the class that defines the component behaviour. Its __init__ method is called to create the component; the parameter self references the DOM element for the custom component.

options is a dictionary with the component options (cf documentation for define). The only available option is "extends".

class MyParagraph:
    def __init__(self):
        self.shadow = self.attachShadow({'mode': 'open'})
        self.shadow <= html.B('hello')

define('my-paragraph', MyParagraph, {'extends': 'p'})

If the component class inherits a class defined in module browser.html, the option "extends" is automatically added, with a value set to the class name. The code above can thus be replaced by

from browser import html

class MyParagraph(html.P):
    def __init__(self):
        self.shadow = self.attachShadow({'mode': 'open'})
        self.shadow <= html.B('hello')

define('my-paragraph', MyParagraph)

get(tag_name)

returns the class associated to tag_name, or None.

Example

Suppose we want to define a custom tag <bold-italic> with an attribute "data-val":

<bold-italic data-val="hello"></bold-italic>

What happens when the tag is found in the HTML document is defined by the method __init__ of the Web Component class BoldItalic.

from browser import webcomponent

class BoldItalic:

    def __init__(self):
        # Create a shadow root
        shadow = self.attachShadow({'mode': 'open'})

        # Insert the value of attribute "data-val" in bold italic
        # in the shadow root
        shadow <= html.B(html.I(self.attrs['data-val']))

# Tell the browser to manage <bold-italic> tags with the class BoldItalic
webcomponent.define("bold-italic", BoldItalic)

Note the use of another DOM technology, ShadowRoot, to define a DOM subtree, different from the main DOM tree.

Life cycle management

The Web Component defines a set of callback functions that manage the life cycle of a custom component.

To implement them in Brython, just add the functions in the class definition:

import browser.webcomponent

class BoldItalic:

    def __init__(self):
        # Create a shadow root
        shadow = self.attachShadow({'mode': 'open'})

        # Insert the value of attribute "data-val" in bold italic
        # in the shadow root
        shadow <= html.B(html.I(self.attrs['data-val']))

    def connectedCallback(self):
        print("connected callback", self)

webcomponent.define("bold-italic", BoldItalic)

To handle changes to some attributes, add list observedAttributes and method attributeChangedCallback() as in the example below (note that this time, a new custom element is created with the function maketag in module browser.html and dynamically added to the document):

observed_tag = html.maketag("observed-element")

class Observed:

    observedAttributes = ["data"]

    def attributeChangedCallback(self, name, old, new, ns):
        print(f"attribute {name} changed from {old} to {new}")

webcomponent.define("observed-element", Observed)

elt = observed_tag()
document <= elt
elt.attrs["data"] = "info"