source: Dev/branches/rest-dojo-ui/client/dojox/dtl/contrib/dom.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 5.2 KB
Line 
1define([
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});
Note: See TracBrowser for help on using the repository browser.