jam 0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/HISTORY +21 -0
- data/MANIFEST +52 -0
- data/README +39 -0
- data/TODO +22 -0
- data/bin/jam +0 -0
- data/demo/array.rb +16 -0
- data/demo/attribute.rb +24 -0
- data/demo/demi/fixtures/ex1.html +10 -0
- data/demo/demi/fixtures/samples.yaml +19 -0
- data/demo/demi/integration/01_jam.rd +41 -0
- data/demo/demi/integration/02_xpath.rd +41 -0
- data/demo/demi/integration/samples.rd +28 -0
- data/demo/demi/unit/hpricot.rd +150 -0
- data/demo/demi/unit/libxml.rd +75 -0
- data/demo/demi/unit/nokogiri.rd +148 -0
- data/demo/demi/unit/rexml.rd +63 -0
- data/demo/hash.rb +20 -0
- data/demo/helloworld.rb +12 -0
- data/demo/object.rb +19 -0
- data/demo/table.rb +24 -0
- data/js/jquery.jam.js +230 -0
- data/lib/jam.rb +2 -0
- data/lib/jam/cherry.rb +1 -0
- data/lib/jam/css2xpath.rb +104 -0
- data/lib/jam/css_to_xpath.rb +132 -0
- data/lib/jam/engine.rb +169 -0
- data/lib/jam/hpricot.rb +137 -0
- data/lib/jam/libxml.rb +151 -0
- data/lib/jam/nokogiri.rb +167 -0
- data/lib/jam/rexml.rb +135 -0
- data/lib/jam/template.rb +224 -0
- data/meta/abstract +2 -0
- data/meta/author +1 -0
- data/meta/created +1 -0
- data/meta/homepage +1 -0
- data/meta/package +1 -0
- data/meta/project +1 -0
- data/meta/status +1 -0
- data/meta/summary +1 -0
- data/meta/timestamp +1 -0
- data/meta/title +1 -0
- data/meta/version +1 -0
- metadata +103 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
= Unit Tests for Jam LibXML Adapter
|
2
|
+
|
3
|
+
Require adapter.
|
4
|
+
|
5
|
+
require "jam/libxml"
|
6
|
+
|
7
|
+
This automatically requires 'libxml' too.
|
8
|
+
|
9
|
+
== LibXML::XML::Document
|
10
|
+
|
11
|
+
=== #jam
|
12
|
+
|
13
|
+
Jam data into a LibXML Document.
|
14
|
+
|
15
|
+
xml = LibXML::XML::Document.string <<-EOS
|
16
|
+
<root><x><m id="a">dummy</m><n id="b">dummy</n></x></root>
|
17
|
+
EOS
|
18
|
+
|
19
|
+
data = {
|
20
|
+
:a => "A",
|
21
|
+
:b => "B"
|
22
|
+
}
|
23
|
+
|
24
|
+
out = xml.jam(data)
|
25
|
+
out = out.root.to_s.gsub(/\n\s*/,'')
|
26
|
+
|
27
|
+
out.should == %{<root><x><m id="a">A</m><n id="b">B</n></x></root>}
|
28
|
+
|
29
|
+
== LibXML::XML::Node
|
30
|
+
|
31
|
+
=== #jam
|
32
|
+
|
33
|
+
Jam data into a LibXML Node.
|
34
|
+
|
35
|
+
xml = LibXML::XML::Document.string <<-EOS
|
36
|
+
<root><x><m id="a">dummy</m><n id="b">dummy</n></x></root>
|
37
|
+
EOS
|
38
|
+
|
39
|
+
node = xml.root
|
40
|
+
|
41
|
+
data = {
|
42
|
+
:a => "A",
|
43
|
+
:b => "B"
|
44
|
+
}
|
45
|
+
|
46
|
+
out = node.jam(data)
|
47
|
+
out = out.to_s.gsub(/\n\s*/,'')
|
48
|
+
|
49
|
+
out.should == %{<root><x><m id="a">A</m><n id="b">B</n></x></root>}
|
50
|
+
|
51
|
+
== LibXML::XML::XPath::Object
|
52
|
+
|
53
|
+
=== #jam
|
54
|
+
|
55
|
+
Jam data into the Nodes of a LibXML::XPath::Object.
|
56
|
+
|
57
|
+
xml = LibXML::XML::Document.string <<-EOS
|
58
|
+
<root><x><m id="a" class="q">dummy</m><n id="b" class="q">dummy</n></x></root>
|
59
|
+
EOS
|
60
|
+
|
61
|
+
nodes = xml.find(".//*[@class='q']") #('.q')
|
62
|
+
|
63
|
+
data = { :a => "A", :b => "B" }
|
64
|
+
|
65
|
+
out = nodes.jam(data)
|
66
|
+
|
67
|
+
# can't get string?
|
68
|
+
out = out.inject(""){ |m, n| m += n.to_s }
|
69
|
+
|
70
|
+
out = out.gsub(/\n\s*/,'')
|
71
|
+
|
72
|
+
out.should == %{<m id="a" class="q">A</m><n id="b" class="q">B</n>}
|
73
|
+
|
74
|
+
QED.
|
75
|
+
|
@@ -0,0 +1,148 @@
|
|
1
|
+
= Unit Tests for Jam Nokogiri Adapter
|
2
|
+
|
3
|
+
Require adapter.
|
4
|
+
|
5
|
+
require "jam/nokogiri"
|
6
|
+
|
7
|
+
This automatically requires 'nokogiri' too.
|
8
|
+
|
9
|
+
== Jam::Nokogiri
|
10
|
+
|
11
|
+
Support objects for following tests.
|
12
|
+
|
13
|
+
@xml = "<root><a>A</a><b>B</b><c>C</c></root>"
|
14
|
+
@eng = Jam::Nokogiri.new
|
15
|
+
|
16
|
+
BEFORE: We will resuse this XML document.
|
17
|
+
|
18
|
+
@doc = @eng.document(@xml)
|
19
|
+
|
20
|
+
=== #append
|
21
|
+
|
22
|
+
Append should be able to append an XML node.
|
23
|
+
|
24
|
+
node = @doc.root
|
25
|
+
node2 = node.children[0].dup
|
26
|
+
|
27
|
+
@eng.append(node, node2)
|
28
|
+
|
29
|
+
out = node.to_s.gsub(/\n\s*/,'')
|
30
|
+
out.should == '<root><a>A</a><b>B</b><c>C</c><a>A</a></root>'
|
31
|
+
|
32
|
+
Append should be able to append a NodeSet.
|
33
|
+
|
34
|
+
node = @doc.root
|
35
|
+
nodeset = @doc.root.children.dup
|
36
|
+
|
37
|
+
@eng.append(node, nodeset)
|
38
|
+
|
39
|
+
out = node.to_s.gsub(/\n\s*/,'')
|
40
|
+
out.should == '<root><a>A</a><b>B</b><c>C</c><a>A</a><b>B</b><c>C</c></root>'
|
41
|
+
|
42
|
+
Append should be able to append an XML text fragment.
|
43
|
+
|
44
|
+
node = @doc.root
|
45
|
+
|
46
|
+
@eng.append(node, '<d>D</d>')
|
47
|
+
|
48
|
+
out = node.to_s.gsub(/\n\s*/,'')
|
49
|
+
out.should == '<root><a>A</a><b>B</b><c>C</c><d>D</d></root>'
|
50
|
+
|
51
|
+
=== #replace_content_with_text
|
52
|
+
|
53
|
+
It should replace node children with given text.
|
54
|
+
|
55
|
+
node = @doc.root
|
56
|
+
|
57
|
+
@eng.replace_content_with_text(node, 'H')
|
58
|
+
|
59
|
+
out = node.to_s.gsub(/\n\s*/,'')
|
60
|
+
out.should == '<root>H</root>'
|
61
|
+
|
62
|
+
It should be able to replace the children of each node of a NodeSet with text.
|
63
|
+
|
64
|
+
node = @doc.root
|
65
|
+
nodeset = @doc.root.children
|
66
|
+
|
67
|
+
@eng.replace_content_with_text(nodeset, 'H')
|
68
|
+
|
69
|
+
out = node.to_s.gsub(/\n\s*/,'')
|
70
|
+
out.should == '<root><a>H</a><b>H</b><c>H</c></root>'
|
71
|
+
|
72
|
+
=== #cleanup
|
73
|
+
|
74
|
+
This will clean a document, or node, of any elements that request it.
|
75
|
+
|
76
|
+
doc = @eng.document('<root><a jam="erase">This is text.</a></root>')
|
77
|
+
|
78
|
+
@eng.cleanup(doc)
|
79
|
+
|
80
|
+
out = doc.root.to_s.gsub(/\n\s*/,'')
|
81
|
+
out.should == '<root>This is text.</root>'
|
82
|
+
|
83
|
+
|
84
|
+
== ::Nokogiri::Document
|
85
|
+
|
86
|
+
=== #jam
|
87
|
+
|
88
|
+
Jam data into a Nokogiri Document.
|
89
|
+
|
90
|
+
xml = Nokogiri::XML <<-EOS
|
91
|
+
<root><x><m id="a">dummy</m><n id="b">dummy</n></x></root>
|
92
|
+
EOS
|
93
|
+
|
94
|
+
data = {
|
95
|
+
:a => "A",
|
96
|
+
:b => "B"
|
97
|
+
}
|
98
|
+
|
99
|
+
out = xml.jam(data)
|
100
|
+
out = out.root.to_s.gsub(/\n\s*/,'')
|
101
|
+
|
102
|
+
out.should == %{<root><x><m id="a">A</m><n id="b">B</n></x></root>}
|
103
|
+
|
104
|
+
== ::Nokogiri::Node
|
105
|
+
|
106
|
+
=== #jam
|
107
|
+
|
108
|
+
Jam data into a Nokogiri Node.
|
109
|
+
|
110
|
+
xml = Nokogiri::XML <<-EOS
|
111
|
+
<root><x><m id="a">dummy</m><n id="b">dummy</n></x></root>
|
112
|
+
EOS
|
113
|
+
|
114
|
+
node = xml.root
|
115
|
+
|
116
|
+
data = {
|
117
|
+
:a => "A",
|
118
|
+
:b => "B"
|
119
|
+
}
|
120
|
+
|
121
|
+
out = node.jam(data)
|
122
|
+
out = out.to_s.gsub(/\n\s*/,'')
|
123
|
+
|
124
|
+
out.should == %{<root><x><m id="a">A</m><n id="b">B</n></x></root>}
|
125
|
+
|
126
|
+
== ::Nokogiri::NodeSet
|
127
|
+
|
128
|
+
=== #jam
|
129
|
+
|
130
|
+
Jam data into a Nokogiri Node.
|
131
|
+
|
132
|
+
xml = Nokogiri::XML <<-EOS
|
133
|
+
<root><x><m id="a" class="q">dummy</m><n id="b" class="q">dummy</n></x></root>
|
134
|
+
EOS
|
135
|
+
|
136
|
+
nodeset = xml.search('.q')
|
137
|
+
|
138
|
+
p nodeset.search('#a')
|
139
|
+
|
140
|
+
data = { :a => "A", :b => "B" }
|
141
|
+
|
142
|
+
out = nodeset.jam(data)
|
143
|
+
out = out.to_s.gsub(/\n\s*/,'')
|
144
|
+
|
145
|
+
out.should == %{<m id="a" class="q">A</m><n id="b" class="q">B</n>}
|
146
|
+
|
147
|
+
QED.
|
148
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
= Unit Tests for Jam REXML Adapter
|
2
|
+
|
3
|
+
Require adapter.
|
4
|
+
|
5
|
+
require "jam/rexml"
|
6
|
+
|
7
|
+
This automatically requires 'rexml/document' too.
|
8
|
+
|
9
|
+
== REXML::Document
|
10
|
+
|
11
|
+
=== #jam
|
12
|
+
|
13
|
+
Jam data into a REXML Document.
|
14
|
+
|
15
|
+
xml = REXML::Document.new <<-EOS
|
16
|
+
<root><x><m id="a">dummy</m><n id="b">dummy</n></x></root>
|
17
|
+
EOS
|
18
|
+
|
19
|
+
data = {:a => "A", :b => "B"}
|
20
|
+
|
21
|
+
out = xml.jam(data)
|
22
|
+
out = out.root.to_s.gsub(/\n\s*/,'')
|
23
|
+
|
24
|
+
out.should == %{<root><x><m id="a">A</m><n id="b">B</n></x></root>}
|
25
|
+
|
26
|
+
== REXML::Node
|
27
|
+
|
28
|
+
=== #jam
|
29
|
+
|
30
|
+
Jam data into a REXML Node.
|
31
|
+
|
32
|
+
xml = REXML::Document.new <<-EOS
|
33
|
+
<root><x><m id="a">dummy</m><n id="b">dummy</n></x></root>
|
34
|
+
EOS
|
35
|
+
|
36
|
+
node = xml.root
|
37
|
+
|
38
|
+
data = {:a => "A", :b => "B"}
|
39
|
+
|
40
|
+
out = node.jam(data)
|
41
|
+
out = out.to_s.gsub(/\n\s*/,'')
|
42
|
+
|
43
|
+
out.should == %{<root><x><m id="a">A</m><n id="b">B</n></x></root>}
|
44
|
+
|
45
|
+
== REXML::XPath
|
46
|
+
|
47
|
+
=== #jam_each
|
48
|
+
|
49
|
+
Jam data into the nodes of a REXML::XPath object.
|
50
|
+
|
51
|
+
xml = REXML::Document.new <<-EOS
|
52
|
+
<root><x><m id="a" class="q">dummy</m><n id="b" class="q">dummy</n></x></root>
|
53
|
+
EOS
|
54
|
+
|
55
|
+
data = { :a => "A", :b => "B" }
|
56
|
+
|
57
|
+
out = REXML::XPath.jam(xml, data)
|
58
|
+
out = out.to_s.gsub(/\n\s*/,'')
|
59
|
+
|
60
|
+
out.should == %{<m id="a" class="q">A</m><n id="b" class="q">B</n>}
|
61
|
+
|
62
|
+
QED.
|
63
|
+
|
data/demo/hash.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'jam'
|
2
|
+
|
3
|
+
tmpl = Jam::Template.new <<-END
|
4
|
+
<html>
|
5
|
+
<body>
|
6
|
+
<h1 id="title">title will be inserted here</h1>
|
7
|
+
<p id="body">body text will be inserted here</p>
|
8
|
+
</body>
|
9
|
+
</html>
|
10
|
+
END
|
11
|
+
|
12
|
+
data = {
|
13
|
+
:title => "hello world",
|
14
|
+
:body => "Amrita is a html template libraly for Ruby"
|
15
|
+
}
|
16
|
+
|
17
|
+
out = tmpl.expand(data)
|
18
|
+
|
19
|
+
puts out
|
20
|
+
|
data/demo/helloworld.rb
ADDED
data/demo/object.rb
ADDED
data/demo/table.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'jam'
|
2
|
+
|
3
|
+
tmpl = Jam::Template.new <<-END
|
4
|
+
<table border="1">
|
5
|
+
<tr><th>name</th><th>author</th></tr>
|
6
|
+
<tr id="table1">
|
7
|
+
<td id="name"></td>
|
8
|
+
<td id="author"></td>
|
9
|
+
</tr>
|
10
|
+
</table>
|
11
|
+
END
|
12
|
+
|
13
|
+
data = {
|
14
|
+
:table1=>[
|
15
|
+
{ :name=>"Ruby", :author=>"Matz" },
|
16
|
+
{ :name=>"Perl", :author=>"Larry Wall" },
|
17
|
+
{ :name=>"Python", :author=>"Guido van Rossum" }
|
18
|
+
]
|
19
|
+
}
|
20
|
+
|
21
|
+
out = tmpl.expand(data)
|
22
|
+
|
23
|
+
puts out
|
24
|
+
|
data/js/jquery.jam.js
ADDED
@@ -0,0 +1,230 @@
|
|
1
|
+
// Jam Templates -- a jQuery Plugin
|
2
|
+
// Copyright (c) 2007,2008 Tiger Ops
|
3
|
+
// http://tigerops.psytower.info
|
4
|
+
//
|
5
|
+
// Jam is a "weaving" template system that
|
6
|
+
// operate fully on the front-end, thus off-loading
|
7
|
+
// some of the back-end work load while also
|
8
|
+
// providing 100% SOC (Seperation of Concern).
|
9
|
+
//
|
10
|
+
// Example:
|
11
|
+
//
|
12
|
+
// data = {
|
13
|
+
// hello: "Hello, World!"
|
14
|
+
// }
|
15
|
+
//
|
16
|
+
// $.jam(data)
|
17
|
+
//
|
18
|
+
// Jam templates are especially useful when
|
19
|
+
// filled via AJAX with JSON data. For this reason
|
20
|
+
// a shortcut is provided.
|
21
|
+
//
|
22
|
+
// $.jam_ajax('http://somewhere/data.json')
|
23
|
+
//
|
24
|
+
|
25
|
+
// FOR DEBUGGING
|
26
|
+
/*
|
27
|
+
function inspect(obj) {
|
28
|
+
var txt = "";
|
29
|
+
for(var prop in obj) {
|
30
|
+
txt += prop + ": " + obj[prop] + "\n";
|
31
|
+
}
|
32
|
+
alert(txt);
|
33
|
+
};
|
34
|
+
*/
|
35
|
+
|
36
|
+
//
|
37
|
+
//
|
38
|
+
//
|
39
|
+
jQuery.jam_ajax = function(url) {
|
40
|
+
result = url.match(/[.]xml$/);
|
41
|
+
if (result != null) {
|
42
|
+
jQuery.getXML(url, jQuery.cherry_xml);
|
43
|
+
} else {
|
44
|
+
jQuery.getJSON(url, jQuery.cherry);
|
45
|
+
}
|
46
|
+
};
|
47
|
+
|
48
|
+
//
|
49
|
+
//
|
50
|
+
//
|
51
|
+
jQuery.getXML = function(url, callback) {
|
52
|
+
jQuery.ajax({
|
53
|
+
dataType: "xml",
|
54
|
+
url: url,
|
55
|
+
success: callback
|
56
|
+
});
|
57
|
+
};
|
58
|
+
|
59
|
+
//
|
60
|
+
// Interpolate XML by converting to JSON.
|
61
|
+
// This only work is xml2json.js is loaded.
|
62
|
+
//
|
63
|
+
jQuery.jam_xml = function(xml) {
|
64
|
+
var json = xml2json(xml,' ');
|
65
|
+
//var data = json.parseJSON();
|
66
|
+
var data = eval('(' + json + ')'); // SECURE ME!
|
67
|
+
jQuery.jam(data);
|
68
|
+
};
|
69
|
+
|
70
|
+
//
|
71
|
+
// Interpolate JSON data.
|
72
|
+
//
|
73
|
+
// TODO: how to do whole document instead of body?
|
74
|
+
jQuery.jam = function(data) {
|
75
|
+
// jQuery('body').interpolate(data);
|
76
|
+
// jQuery('body').jam_cleanup();
|
77
|
+
jQuery.interpolate(data);
|
78
|
+
jQuery.jam_cleanup();
|
79
|
+
};
|
80
|
+
|
81
|
+
//
|
82
|
+
// Remove any unwanted jam tags.
|
83
|
+
//
|
84
|
+
// TODO: remove jam attributes too.
|
85
|
+
jQuery.jam_cleanup = function() {
|
86
|
+
jQuery("[@jam='erase']").unwrap();
|
87
|
+
};
|
88
|
+
|
89
|
+
//
|
90
|
+
// Interpolate data into template nodes.
|
91
|
+
//
|
92
|
+
jQuery.fn.interpolate = function(data) {
|
93
|
+
if(!data) {
|
94
|
+
this.remove();
|
95
|
+
}
|
96
|
+
else if (data instanceof Array) {
|
97
|
+
this.interpolate_sequence(data);
|
98
|
+
}
|
99
|
+
else if(data instanceof Object) {
|
100
|
+
this.interpolate_object(data);
|
101
|
+
}
|
102
|
+
else {
|
103
|
+
this.interpolate_scalar(data);
|
104
|
+
};
|
105
|
+
return this;
|
106
|
+
};
|
107
|
+
|
108
|
+
//
|
109
|
+
// Interpolate object mapping.
|
110
|
+
//
|
111
|
+
jQuery.fn.interpolate_object = function(data) {
|
112
|
+
var qry;
|
113
|
+
var attr;
|
114
|
+
var tag;
|
115
|
+
var result;
|
116
|
+
var match;
|
117
|
+
|
118
|
+
for (var id in data) {
|
119
|
+
attr = false;
|
120
|
+
tag = false;
|
121
|
+
qry = id;
|
122
|
+
|
123
|
+
result = qry.match(/^<(.*?)>$/);
|
124
|
+
if (result != null) {
|
125
|
+
tag = true;
|
126
|
+
qry = result[1];
|
127
|
+
};
|
128
|
+
|
129
|
+
result = qry.match(/^((.*?)\/)?([@](.*?))$/);
|
130
|
+
if (result != null) {
|
131
|
+
if (result[2] == undefined) { result[2] = null };
|
132
|
+
attr = result[4];
|
133
|
+
qry = result[2] //+ '[@' + attr + ']';
|
134
|
+
}
|
135
|
+
else {
|
136
|
+
attr = false;
|
137
|
+
};
|
138
|
+
|
139
|
+
if (attr == false) {
|
140
|
+
if (tag == false) { qry = '#' + qry; }
|
141
|
+
// probably change to use 'ref' attribute instead of 'id'
|
142
|
+
match = this.find(qry)
|
143
|
+
if (match.size() > 0) {
|
144
|
+
match.interpolate(data[id]);
|
145
|
+
}
|
146
|
+
}
|
147
|
+
else {
|
148
|
+
//qry = qry + '[@' + attr + ']';
|
149
|
+
//this.find(qry).attr(attr,data[id]);
|
150
|
+
if (qry != null) {
|
151
|
+
if (tag == false) { qry = '#' + qry; }
|
152
|
+
this.find(qry).attr(attr,data[id]);
|
153
|
+
} else {
|
154
|
+
this.attr(attr,data[id]);
|
155
|
+
}
|
156
|
+
};
|
157
|
+
};
|
158
|
+
};
|
159
|
+
|
160
|
+
//
|
161
|
+
// Interpolate attribute.
|
162
|
+
//
|
163
|
+
// TODO
|
164
|
+
|
165
|
+
//
|
166
|
+
// Interpolate array sequence.
|
167
|
+
//
|
168
|
+
jQuery.fn.interpolate_sequence = function(data) {
|
169
|
+
var temp = this.clone();
|
170
|
+
this.empty();
|
171
|
+
for (var i in data) {
|
172
|
+
var newNode = temp.clone();
|
173
|
+
newNode.interpolate(data[i]);
|
174
|
+
this.append(newNode); //.children());
|
175
|
+
};
|
176
|
+
};
|
177
|
+
|
178
|
+
//
|
179
|
+
// Interpolate scalar value.
|
180
|
+
//
|
181
|
+
// TODO: Should this has some special HTML features?
|
182
|
+
//
|
183
|
+
// TODO: Should we have two modes --one with and one
|
184
|
+
// without the extra HTML features?
|
185
|
+
//
|
186
|
+
jQuery.fn.interpolate_scalar = function(data) {
|
187
|
+
//var all_special = new Array;
|
188
|
+
|
189
|
+
// text inputs
|
190
|
+
//var special = this.find('input[@type=text]');
|
191
|
+
//special.val(data.toString());
|
192
|
+
//all_special.concat(special);
|
193
|
+
// textarea
|
194
|
+
// TODO
|
195
|
+
|
196
|
+
//this.not(special).empty();
|
197
|
+
//this.not(special).append(data.toString());
|
198
|
+
//alert(data);
|
199
|
+
this.empty();
|
200
|
+
this.append(data.toString());
|
201
|
+
};
|
202
|
+
|
203
|
+
//
|
204
|
+
// Unwrap a node, such that the outer tag is
|
205
|
+
// removed, leaving only it's own children.
|
206
|
+
//
|
207
|
+
jQuery.fn.unwrap = function(expr) {
|
208
|
+
return this.each(function(){
|
209
|
+
$(this).parents(expr).eq(0).after(this).remove();
|
210
|
+
});
|
211
|
+
};
|
212
|
+
|
213
|
+
|
214
|
+
|
215
|
+
/*
|
216
|
+
// Interpolate list.
|
217
|
+
|
218
|
+
function interpolate_list(node, data) {
|
219
|
+
temp = node.copy(true)
|
220
|
+
node.empty!
|
221
|
+
for (var d in data) {
|
222
|
+
nc = temp.copy(true);
|
223
|
+
interpolate_children( nc, d )
|
224
|
+
for (var c in nc.children) {
|
225
|
+
node.add(c);
|
226
|
+
};
|
227
|
+
};
|
228
|
+
};
|
229
|
+
*/
|
230
|
+
|