📄 html.js
字号:
}, setParent: function(node, /*Boolean?*/ up, /*Boolean?*/ root){ if(!this._parent) this._parent = this._first = node; if(up && root && node === this._first){ this._closed = true; } if(up){ var parent = this._parent; var script = ""; var ie = dojo.isIE && parent.tagName == "SCRIPT"; if(ie){ parent.text = ""; } if(parent._dirty){ var caches = parent._cache; for(var i = 0, cache; cache = caches[i]; i++){ if(cache !== parent){ this.onAddNode(cache); if(ie){ script += cache.data; }else{ parent.appendChild(cache); } this.onAddNodeComplete(cache); } } caches.length = 0; parent._dirty = false; } if(ie){ parent.text = script; } } this.onSetParent(node, up); this._parent = node; return this; }, getParent: function(){ return this._parent; }, getRootNode: function(){ return this.rootNode; }, onSetParent: function(node, up){ // summary: Stub called when setParent is used. }, onAddNode: function(node){ // summary: Stub called before new nodes are added }, onAddNodeComplete: function(node){ // summary: Stub called after new nodes are added }, onRemoveNode: function(node){ // summary: Stub called when nodes are removed }, onClone: function(/*DOMNode*/ from, /*DOMNode*/ to){ // summary: Stub called when a node is duplicated }, onAddEvent: function(/*DOMNode*/ node, /*String*/ type, /*String*/ description){ // summary: Stub to call when you're adding an event } }); dd._HtmlNode = dojo.extend(function(node){ // summary: Places a node into DOM this.contents = node; }, { render: function(context, buffer){ this._rendered = true; return buffer.concat(this.contents); }, unrender: function(context, buffer){ if(!this._rendered){ return buffer; } this._rendered = false; return buffer.remove(this.contents); }, clone: function(buffer){ return new this.constructor(this.contents); } }); dd._HtmlNodeList = dojo.extend(function(/*Node[]*/ nodes){ // summary: A list of any HTML-specific node object // description: // Any object that's used in the constructor or added // through the push function much implement the // render, unrender, and clone functions. this.contents = nodes || []; }, { push: function(node){ this.contents.push(node); }, unshift: function(node){ this.contents.unshift(node); }, render: function(context, buffer, /*Node*/ instance){ buffer = buffer || dd.HtmlTemplate.prototype.getBuffer(); if(instance){ var parent = buffer.getParent(); } for(var i = 0; i < this.contents.length; i++){ buffer = this.contents[i].render(context, buffer); if(!buffer) throw new Error("Template node render functions must return their buffer"); } if(parent){ buffer.setParent(parent); } return buffer; }, dummyRender: function(context, buffer, asNode){ // summary: A really expensive way of checking to see how a rendering will look. // Used in the ifchanged tag var div = document.createElement("div"); var parent = buffer.getParent(); var old = parent._clone; // Tell the clone system to attach itself to our new div parent._clone = div; var nodelist = this.clone(buffer, div); if(old){ // Restore state if there was a previous clone parent._clone = old; }else{ // Remove if there was no clone parent._clone = null; } buffer = dd.HtmlTemplate.prototype.getBuffer(); nodelist.unshift(new dd.ChangeNode(div)); nodelist.push(new dd.ChangeNode(div, true)); nodelist.render(context, buffer); if(asNode){ return buffer.getRootNode(); } var html = div.innerHTML; return (dojo.isIE) ? html.replace(/\s*_(dirty|clone)="[^"]*"/g, "") : html; }, unrender: function(context, buffer){ for(var i = 0; i < this.contents.length; i++){ buffer = this.contents[i].unrender(context, buffer); if(!buffer) throw new Error("Template node render functions must return their buffer"); } return buffer; }, clone: function(buffer){ // summary: // Used to create an identical copy of a NodeList, useful for things like the for tag. var parent = buffer.getParent(); var contents = this.contents; var nodelist = new dd._HtmlNodeList(); var cloned = []; for(var i = 0; i < contents.length; i++){ var clone = contents[i].clone(buffer); if(clone instanceof dd.ChangeNode || clone instanceof dd._HtmlNode){ var item = clone.contents._clone; if(item){ clone.contents = item; }else if(parent != clone.contents && clone instanceof dd._HtmlNode){ var node = clone.contents; clone.contents = clone.contents.cloneNode(false); buffer.onClone(node, clone.contents); cloned.push(node); node._clone = clone.contents; } } nodelist.push(clone); } for(var i = 0, clone; clone = cloned[i]; i++){ clone._clone = null; } return nodelist; } }); dd._HtmlVarNode = dojo.extend(function(str){ // summary: A node to be processed as a variable // description: // Will render an object that supports the render function // and the getRootNode function this.contents = new dd._Filter(str); this._lists = {}; }, { render: function(context, buffer){ this._rendered = true; var str = this.contents.resolve(context); if(str && str.render && str.getRootNode){ var root = this._curr = str.getRootNode(); var lists = this._lists; var list = lists[root]; if(!list){ list = lists[root] = new dd._HtmlNodeList(); list.push(new dd.ChangeNode(buffer.getParent())); list.push(new dd._HtmlNode(root)); list.push(str); list.push(new dd.ChangeNode(buffer.getParent())); } return list.render(context, buffer); }else{ if(!this._txt){ this._txt = document.createTextNode(str); } this._txt.data = str; return buffer.concat(this._txt); } }, unrender: function(context, buffer){ if(!this._rendered){ return buffer; } this._rendered = false; if(this._curr){ return this._lists[this._curr].unrender(context, buffer); }else if(this._txt){ return buffer.remove(this._txt); } return buffer; }, clone: function(){ return new this.constructor(this.contents.getExpression()); } }); dd.ChangeNode = dojo.extend(function(node, /*Boolean?*/ up, /*Bookean*/ root){ // summary: Changes the parent during render/unrender this.contents = node; this.up = up; this.root = root; }, { render: function(context, buffer){ return buffer.setParent(this.contents, this.up, this.root); }, unrender: function(context, buffer){ if(!this.contents.parentNode){ return buffer; } if(!buffer.getParent()){ return buffer; } return buffer.setParent(this.contents); }, clone: function(){ return new this.constructor(this.contents, this.up, this.root); } }); dd.AttributeNode = dojo.extend(function(key, value, nodelist){ // summary: Works on attributes this.key = key; this.value = value; this.nodelist = nodelist || (new dd.Template(value)).nodelist; this.contents = ""; }, { render: function(context, buffer){ var key = this.key; var value = this.nodelist.dummyRender(context); if(this._rendered){ if(value != this.contents){ this.contents = value; return buffer.setAttribute(key, value); } }else{ this._rendered = true; this.contents = value; return buffer.setAttribute(key, value); } return buffer; }, unrender: function(context, buffer){ return buffer.remove(this.key); }, clone: function(buffer){ return new this.constructor(this.key, this.value, this.nodelist.clone(buffer)); } }); dd._HtmlTextNode = dojo.extend(function(str){ // summary: Adds a straight text node without any processing this.contents = document.createTextNode(str); }, { set: function(data){ this.contents.data = data; }, render: function(context, buffer){ return buffer.concat(this.contents); }, unrender: function(context, buffer){ return buffer.remove(this.contents); }, clone: function(){ return new this.constructor(this.contents.data); } }); dd._HtmlParser = dojo.extend(function(tokens){ // summary: Turn a simple array into a set of objects // description: // This is also used by all tags to move through // the list of nodes. this.contents = tokens; }, { i: 0, parse: function(/*Array?*/ stop_at){ var types = ddh.types; var terminators = {}; var tokens = this.contents; if(!stop_at){ stop_at = []; } for(var i = 0; i < stop_at.length; i++){ terminators[stop_at[i]] = true; } var nodelist = new dd._HtmlNodeList(); while(this.i < tokens.length){ var token = tokens[this.i++]; var type = token[0]; var value = token[1]; if(type == types.custom){ nodelist.push(value); }else if(type == types.change){ var changeNode = new dd.ChangeNode(value, token[2], token[3]); value[changeNode.attr] = changeNode; nodelist.push(changeNode); }else if(type == types.attr){ var fn = ddt.getTag("attr:" + token[2], true); if(fn && token[3]){ nodelist.push(fn(null, token[2] + " " + token[3])); }else if(dojo.isString(token[3]) && (token[3].indexOf("{%") != -1 || token[3].indexOf("{{") != -1)){ nodelist.push(new dd.AttributeNode(token[2], token[3])); } }else if(type == types.elem){ var fn = ddt.getTag("node:" + value.tagName.toLowerCase(), true); if(fn){ // TODO: We need to move this to tokenization so that it's before the // node and the parser can be passed here instead of null nodelist.push(fn(null, value, value.tagName.toLowerCase())); } nodelist.push(new dd._HtmlNode(value)); }else if(type == types.varr){ nodelist.push(new dd._HtmlVarNode(value)); }else if(type == types.text){ nodelist.push(new dd._HtmlTextNode(value.data || value)); }else if(type == types.tag){ if(terminators[value]){ --this.i; return nodelist; } var cmd = value.split(/\s+/g); if(cmd.length){ cmd = cmd[0]; var fn = ddt.getTag(cmd); if(typeof fn != "function"){ throw new Error("Function not found for " + cmd); } var tpl = fn(this, value); if(tpl){ nodelist.push(tpl); } } } } if(stop_at.length){ throw new Error("Could not find closing tag(s): " + stop_at.toString()); } return nodelist; }, next: function(){ // summary: Used by tags to discover what token was found var token = this.contents[this.i++]; return {type: token[0], text: token[1]}; }, skipPast: function(endtag){ return dd.Parser.prototype.skipPast.call(this, endtag); }, getVarNodeConstructor: function(){ return dd._HtmlVarNode; }, getTextNodeConstructor: function(){ return dd._HtmlTextNode; }, getTemplate: function(/*String*/ loc){ return new dd.HtmlTemplate(ddh.getTemplate(loc)); } });})();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -