-
Notifications
You must be signed in to change notification settings - Fork 2
Defining Elements
Sometimes, you might want to create a new kind of element. Suppose I hadn't defined the List
class -- how would you make a List
for yourself?
The answer involves a lot of HTML. Basically, every Element
is just a wrapper around some HTML tag, which is the tag displayed in the browser. You write an Element
subclass which defines methods that modify the HTML tag. It's that simple.
To succeed here, you'll need to be familiar with HTML (at least enough to write the HTML to display your element), and the DOM API (the most useful pieces are on the Element and Document).
Every element has an HTML tag associated with it. The tag is created by Element.__init__
, which must be given a tag_name
(e.g. "ol"
for a list or "span"
for a piece of text). The tag is an instance of xml.dom.minidom.Element
.
Each element has complete control over its tag, and may do anything it likes to the tag or any descendant of the tag, with the following exceptions:
- do not modify the element's tag's
id
orstyle
attributes, or any attributes beginning withon
(used for event-handling) - do not modify your children's tags, or their descendants
For example, a List instance with two children would have a tag that looks like
<ol>
<li>
<someTag for-first-child> ... </someTag>
</li>
<li>
<someTag for-second-child> ... </someTag>
</li>
</ol>
The List instance is free to modify the ol
or li
tags in any way, including inserting or deleting tags; but it must treat the two someTag
tags as black boxes.
After modifying an element's tag, the element's mark_dirty()
method should be called. If the element is in a GUI being viewed in a browser, e.mark_dirty()
will make sure the browser's version of the tag is up to date.
If you want to do CSS stuff, use the Element's css
attribute. e.css
is a dict-like object that, when modified, will modify the HTML tag and mark the tag as dirty.
I recently overhauled the event-handling framework, and still have to document it. Stay tuned. Sorry!
Using what we know so far, let's implement a List element.
First, we need to figure out what the HTML should look like. Any HTML dabbler will know that it should look like
<ol>
<li>
<tag-for-first-child />
</li>
<li>
<tag-for-second-child />
</li>
...
</ol>
Now, let's define a SimpleList
class, which supports appending and deletion of child elements.
class SimpleList(Element):
def __init__(self, **kwargs):
super(SimpleList, self).__init__(tag_name="ol", **kwargs)
def append(self, new_child):
# add a new item to our HTML list tag
li = self.tag.ownerDocument.createElement('li')
self.tag.appendChild(li)
li.appendChild(new_child.tag)
# make sure the tag gets redrawn
self.mark_dirty()
def delete(self, old_child):
# remove the item containing the child from our HTML list tag
self.tag.removeChild(old_child.tag.parentNode)
# make sure the tag gets redrawn
self.mark_dirty()
That's it! You now know everything there is to know about defining your own elements.