Skip to content

Commit

Permalink
Dynamic tree display; next up: property monitoring
Browse files Browse the repository at this point in the history
  • Loading branch information
julien@igel.co.jp committed Apr 11, 2012
1 parent 7a02928 commit 27b05c6
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 14 deletions.
29 changes: 17 additions & 12 deletions bender.js
Expand Up @@ -50,6 +50,7 @@
context._refreshed_instance = function(instance)
{
flexo.remove_from_array(render_queue, instance);
flexo.notify(this, "@refresh", { instance: instance });
};
context._refresh_instance = function(instance)
{
Expand Down Expand Up @@ -255,8 +256,7 @@
// Render content: record the top-level target for this content,
// the <content> node itself to fetch its attributes, the target
// instance (since we may switch instances to record ids inside
// this node) and the parent content (TODO we don't use this at
// the moment, but we should?)
// this node) and the parent content
content = { target: dest, node: ch, instance: this,
parent: content };
if (this.use.childNodes.length > 0) {
Expand Down Expand Up @@ -295,16 +295,21 @@
d.setAttribute(attr.localName, attr.value);
}
}, this);
if (content && dest === content.target) {
[].forEach.call(content.node.attributes, function(attr) {
if (attr.name === "id") return;
if (attr.name === "content-id") {
content.instance.views[attr.value.trim()] = d;
} else {
d.setAttribute(attr.name, attr.value);
}
});
}
var content_id = function(content) {
if (content && dest === content.target) {
flexo.log("content: node=", content.node, "parent=", content.parent);
content_id(content.parent);
[].forEach.call(content.node.attributes, function(attr) {
if (attr.name === "id") return;
if (attr.name === "content-id") {
content.instance.views[attr.value.trim()] = d;
} else {
d.setAttribute(attr.name, attr.value);
}
});
}
};
content_id(content);
dest.insertBefore(d, ref);
if (dest === this.target) {
[].forEach.call(this.use.attributes, function(attr) {
Expand Down
8 changes: 8 additions & 0 deletions index.html
Expand Up @@ -345,6 +345,8 @@ <h4>The component, app and context elements</h4>
href="https://github.com/bendr/bender/blob/master/lib/timer.xml">timer</a>,
or larger components relying on other components like toolbars,
dialogs, all the way to complete applications.</p>
<p><span class="TODO">Document @refresh event from context when
component instances are refreshed.</span></p>
</section>

<section id="manual.elements.use">
Expand Down Expand Up @@ -762,6 +764,12 @@ <h2>Library</h2>
controls to modify the top-level parameters of the application. Use
the <code class="attr">href</code> attribute as well (see applications
above for examples.)</li>
<li><a href="lib/tree.html">Runtime with dynamic tree view</a>: show
the tree of the application running (<span class="TODO">and edit the
tree</span>.) Use the <code class="attr">href</code> attribute as
well (see applications above for examples; a <a
href="lib/tree.html?href=../tests/control2.xml">simple
example</a>.)</li>
<li><a
href="https://github.com/bendr/bender/blob/master/lib/button.xml">Button</a></li>
<li><a
Expand Down
46 changes: 46 additions & 0 deletions lib/tree.html
@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>⚐ Bender tree view</title>
<meta charset="UTF-8">
<meta http-equiv="cache-control" content="no-cache">
<style>
body {
font-family: Univers, "Helvetica Neue", Helvetica, sans-serif;
padding: 0;
margin: 0;
}
.app { padding: 4px 8px; }
</style>
<script src="../flexo.js"></script>
<script src="../bender.js"></script>
</head>
<body>
<script>

var load = function()
{
if (this.uses.app) {
this.uses.tree.make_tree_from_node(this.uses.app.component);
}
};

var args = flexo.get_args();
args.id = "app";
var context = bender.create_context(document.body);
if (args.href) {
var use = context.$("use", args);
context.appendChild(
context.$("component",
context.$("view",
context.$("use", { href: "tree.xml", id: "tree" }),
context.$("html:div.app",
context.$("use", args))),
context.$("watch",
context.$get({ use: "$self", event: "@rendered" }, load))));
context.appendChild(context.$("use", { q: "component" }));
}

</script>
</body>
</html>
67 changes: 67 additions & 0 deletions lib/tree.xml
@@ -0,0 +1,67 @@
<component xmlns="http://bender.igel.co.jp"
xmlns:html="http://www.w3.org/1999/xhtml">
<title>Bender tree visualizer</title>

<view>
<target q="head" once="true">
<html:style>
.bender_tree { border-bottom: dashed thin black; padding-bottom: 8px;
background-color: white; margin-top: 0; padding-top: 8px; }
ul.bender_tree, ul.bender_tree ul { list-style-type: none; }
.bender_tree span.tag { font-weight: bold; }
.bender_tree span.attr { font-style: italic; }
.bender_tree span.attr-value { font-family: monospace; }
.bender_tree li.text { font-family: monospace; white-space: pre }
</html:style>
</target>
<html:ul id="ul" class="bender_tree"/>
</view>

<script><![CDATA[
this._prototype.make_tree_from_node = function(node)
{
flexo.listen(node.ownerDocument, "@refresh", (function(e) {
var component = e.instance.component;
var li = component.__li;
if (li) {
var parent = li.parentNode;
var ref = li.nextSibling;
parent.removeChild(li);
parent.insertBefore(this.li_for_node(component), ref);
}
}).bind(this));
this.views.ul.appendChild(this.li_for_node(node));
};
this._prototype.li_for_node = function(node)
{
if (node.nodeType === 1) {
var li = this.component.$("html:li.elem",
this.component.$("html:span.tag", node.localName));
[].forEach.call(node.attributes, function(attr) {
if (!/^xmlns:?/.test(attr.name)) {
li.appendChild(this.component.ownerDocument.createTextNode(" "));
li.appendChild(this.component.$("html:span.attr", attr.name));
li.appendChild(this.component.ownerDocument.createTextNode("="));
li.appendChild(this.component.$("html:span.attr-value",
attr.value));
}
}, this);
var ul = li.appendChild(this.component.$("html:ul"));
[].forEach.call(node.childNodes, function(ch) {
var new_li = this.li_for_node(ch);
if (new_li) ul.appendChild(new_li);
}, this);
if (ul.childNodes.length === 0) li.removeChild(ul);
node.__li = li;
return li;
} else if ((node.nodeType === 3 || node.nodeType === 4) &&
/\S/.test(node.textContent)) {
return this.component.$("html:li.text", node.textContent);
}
};
]]></script>

</component>
4 changes: 2 additions & 2 deletions tests/hello.xml
@@ -1,7 +1,7 @@
<component xmlns="http://bender.igel.co.jp">
<app xmlns="http://bender.igel.co.jp">
<view>
<p xmlns="http://www.w3.org/1999/xhtml">
Hello, world!
</p>
</view>
</component>
</app>

0 comments on commit 27b05c6

Please sign in to comment.