1 | define([ |
---|
2 | "dojo/_base/kernel", |
---|
3 | "dojo/_base/lang", |
---|
4 | "dojo/_base/connect", |
---|
5 | "dojo/dom-style", |
---|
6 | "dojo/dom-construct", |
---|
7 | "../_base", |
---|
8 | "../dom" |
---|
9 | ], function(kernel,lang,connect,domStyle,domConstruct,dd,dddom){ |
---|
10 | /*===== |
---|
11 | dd = dojox.dtl; |
---|
12 | =====*/ |
---|
13 | var ddch = lang.getObject("dojox.dtl.contrib.dom", true); |
---|
14 | |
---|
15 | var simple = {render: function(){ return this.contents; }}; |
---|
16 | |
---|
17 | ddch.StyleNode = lang.extend(function(styles){ |
---|
18 | this.contents = {}; |
---|
19 | this._current = {}; |
---|
20 | this._styles = styles; |
---|
21 | for(var key in styles){ |
---|
22 | if(styles[key].indexOf("{{") != -1){ |
---|
23 | var node = new dd.Template(styles[key]); |
---|
24 | }else{ |
---|
25 | var node = lang.delegate(simple); |
---|
26 | node.contents = styles[key]; |
---|
27 | } |
---|
28 | this.contents[key] = node; |
---|
29 | } |
---|
30 | }, |
---|
31 | { |
---|
32 | render: function(context, buffer){ |
---|
33 | for(var key in this.contents){ |
---|
34 | var value = this.contents[key].render(context); |
---|
35 | if(this._current[key] != value){ |
---|
36 | domStyle.set(buffer.getParent(), key, this._current[key] = value); |
---|
37 | } |
---|
38 | } |
---|
39 | return buffer; |
---|
40 | }, |
---|
41 | unrender: function(context, buffer){ |
---|
42 | this._current = {}; |
---|
43 | return buffer; |
---|
44 | }, |
---|
45 | clone: function(buffer){ |
---|
46 | return new this.constructor(this._styles); |
---|
47 | } |
---|
48 | }); |
---|
49 | |
---|
50 | ddch.BufferNode = lang.extend(function(nodelist, options){ |
---|
51 | this.nodelist = nodelist; |
---|
52 | this.options = options; |
---|
53 | }, |
---|
54 | { |
---|
55 | _swap: function(type, node){ |
---|
56 | if(!this.swapped && this.parent.parentNode){ |
---|
57 | if(type == "node"){ |
---|
58 | if((node.nodeType == 3 && !this.options.text) || (node.nodeType == 1 && !this.options.node)){ |
---|
59 | return; |
---|
60 | } |
---|
61 | }else if(type == "class"){ |
---|
62 | if(type != "class"){ |
---|
63 | return; |
---|
64 | } |
---|
65 | } |
---|
66 | |
---|
67 | this.onAddNode && connect.disconnect(this.onAddNode); |
---|
68 | this.onRemoveNode && connect.disconnect(this.onRemoveNode); |
---|
69 | this.onChangeAttribute && connect.disconnect(this.onChangeAttribute); |
---|
70 | this.onChangeData && connect.disconnect(this.onChangeData); |
---|
71 | |
---|
72 | this.swapped = this.parent.cloneNode(true); |
---|
73 | this.parent.parentNode.replaceChild(this.swapped, this.parent); |
---|
74 | } |
---|
75 | }, |
---|
76 | render: function(context, buffer){ |
---|
77 | this.parent = buffer.getParent(); |
---|
78 | if(this.options.node){ |
---|
79 | this.onAddNode = connect.connect(buffer, "onAddNode", lang.hitch(this, "_swap", "node")); |
---|
80 | this.onRemoveNode = connect.connect(buffer, "onRemoveNode", lang.hitch(this, "_swap", "node")); |
---|
81 | } |
---|
82 | if(this.options.text){ |
---|
83 | this.onChangeData = connect.connect(buffer, "onChangeData", lang.hitch(this, "_swap", "node")); |
---|
84 | } |
---|
85 | if(this.options["class"]){ |
---|
86 | this.onChangeAttribute = connect.connect(buffer, "onChangeAttribute", lang.hitch(this, "_swap", "class")); |
---|
87 | } |
---|
88 | |
---|
89 | buffer = this.nodelist.render(context, buffer); |
---|
90 | |
---|
91 | if(this.swapped){ |
---|
92 | this.swapped.parentNode.replaceChild(this.parent, this.swapped); |
---|
93 | domConstruct.destroy(this.swapped); |
---|
94 | }else{ |
---|
95 | this.onAddNode && connect.disconnect(this.onAddNode); |
---|
96 | this.onRemoveNode && connect.disconnect(this.onRemoveNode); |
---|
97 | this.onChangeAttribute && connect.disconnect(this.onChangeAttribute); |
---|
98 | this.onChangeData && connect.disconnect(this.onChangeData); |
---|
99 | } |
---|
100 | |
---|
101 | delete this.parent; |
---|
102 | delete this.swapped; |
---|
103 | return buffer; |
---|
104 | }, |
---|
105 | unrender: function(context, buffer){ |
---|
106 | return this.nodelist.unrender(context, buffer); |
---|
107 | }, |
---|
108 | clone: function(buffer){ |
---|
109 | return new this.constructor(this.nodelist.clone(buffer), this.options); |
---|
110 | } |
---|
111 | }); |
---|
112 | |
---|
113 | lang.mixin(ddch, { |
---|
114 | buffer: function(parser, token){ |
---|
115 | // summary: |
---|
116 | // Buffer large DOM manipulations during re-render. |
---|
117 | // description: |
---|
118 | // When using DomTemplate, wrap any content |
---|
119 | // that you expect to change often during |
---|
120 | // re-rendering. It will then remove its parent |
---|
121 | // from the main document while it re-renders that |
---|
122 | // section of code. It will only remove it from |
---|
123 | // the main document if a mainpulation of somes sort |
---|
124 | // happens. ie It won't swap out if it diesn't have to. |
---|
125 | // example: |
---|
126 | // By default, it considers only node addition/removal |
---|
127 | // to be "changing" |
---|
128 | // |
---|
129 | // | {% buffer %}{% for item in items %}<li>{{ item }}</li>{% endfor %}{% endbuffer %} |
---|
130 | // example: |
---|
131 | // You can explicitly declare options: |
---|
132 | // |
---|
133 | // * node: Watch node removal/addition |
---|
134 | // * class: Watch for a classname to be changed |
---|
135 | // * text: Watch for any text to be changed |
---|
136 | // |
---|
137 | // | {% buffer node class %}{% for item in items %}<li>{{ item }}</li>{% endfor %}{% endbuffer %} |
---|
138 | var parts = token.contents.split().slice(1); |
---|
139 | var options = {}; |
---|
140 | var found = false; |
---|
141 | for(var i = parts.length; i--;){ |
---|
142 | found = true; |
---|
143 | options[parts[i]] = true; |
---|
144 | } |
---|
145 | if(!found){ |
---|
146 | options.node = true; |
---|
147 | } |
---|
148 | var nodelist = parser.parse(["endbuffer"]); |
---|
149 | parser.next_token(); |
---|
150 | return new ddch.BufferNode(nodelist, options); |
---|
151 | }, |
---|
152 | html: function(parser, token){ |
---|
153 | kernel.deprecated("{% html someVariable %}", "Use {{ someVariable|safe }} instead"); |
---|
154 | return parser.create_variable_node(token.contents.slice(5) + "|safe"); |
---|
155 | }, |
---|
156 | style_: function(parser, token){ |
---|
157 | var styles = {}; |
---|
158 | token = token.contents.replace(/^style\s+/, ""); |
---|
159 | var rules = token.split(/\s*;\s*/g); |
---|
160 | for(var i = 0, rule; rule = rules[i]; i++){ |
---|
161 | var parts = rule.split(/\s*:\s*/g); |
---|
162 | var key = parts[0]; |
---|
163 | var value = lang.trim(parts[1]); |
---|
164 | if(value){ |
---|
165 | styles[key] = value; |
---|
166 | } |
---|
167 | } |
---|
168 | return new ddch.StyleNode(styles); |
---|
169 | } |
---|
170 | }); |
---|
171 | |
---|
172 | dd.register.tags("dojox.dtl.contrib", { |
---|
173 | "dom": ["html", "attr:style", "buffer"] |
---|
174 | }); |
---|
175 | return dojox.dtl.contrib.dom; |
---|
176 | }); |
---|