diff --git a/dist/moon.js b/dist/moon.js index 180e6249..32054747 100644 --- a/dist/moon.js +++ b/dist/moon.js @@ -1216,23 +1216,29 @@ // Generate all other attributes for (var attr in attrs) { + // Attribute Info + var attrInfo = attrs[attr]; + // Get attr by it's actual name (in case it had any arguments) - var attrName = attrs[attr].name; + var attrName = attrInfo.name; + + // Late bind for special directive + var specialDirective = null; // If it is a directive, mark it as dynamic - if (specialDirectives[attrName]) { + if ((specialDirective = specialDirectives[attrName]) !== undefined) { // Generate Special Directives // Special directive found that generates code after initial generation, push it to its known special directives to run afterGenerate later - if (specialDirectives[attrName].afterGenerate) { + if (specialDirective.afterGenerate) { if (!vnode.specialDirectivesAfter) { vnode.specialDirectivesAfter = {}; } - vnode.specialDirectivesAfter[attr] = attrs[attr]; + vnode.specialDirectivesAfter[attr] = attrInfo; } // Invoke any special directives that need to change values of props during code generation - if (specialDirectives[attrName].duringPropGenerate) { - generatedObject += specialDirectives[attrName].duringPropGenerate(attrs[attr].value, attrs[attr].meta, vnode); + if (specialDirective.duringPropGenerate) { + generatedObject += specialDirective.duringPropGenerate(attrInfo.value, attrInfo.meta, vnode); } // Keep a flag to know to always rerender this @@ -1241,10 +1247,10 @@ // Remove special directive delete attrs[attr]; } else if (directives[attrName]) { - vnode.props.directives.push(attrs[attr]); + vnode.props.directives.push(attrInfo); vnode.meta.shouldRender = true; } else { - var normalizedProp = JSON.stringify(attrs[attr].value); + var normalizedProp = JSON.stringify(attrInfo.value); var compiledProp = compileTemplate(normalizedProp, true); if (normalizedProp !== compiledProp) { vnode.meta.shouldRender = true; @@ -1253,7 +1259,8 @@ } } - if (Object.keys(attrs).length) { + // Close object + if (Object.keys(attrs).length !== 0) { generatedObject = generatedObject.slice(0, -2) + "}"; } else { generatedObject += "}"; @@ -1262,12 +1269,17 @@ // Check for DOM Properties var dom = vnode.props.dom; - if (dom) { + if (dom !== undefined) { vnode.meta.shouldRender = true; + // Add dom property generatedObject += ", dom: {"; + + // Generate all properties for (var domProp in dom) { generatedObject += '"' + domProp + '": ' + dom[domProp] + ', '; } + + // Close object generatedObject = generatedObject.slice(0, -2) + "}"; } @@ -1278,14 +1290,16 @@ for (var i = 0; i < allDirectives.length; i++) { var directiveInfo = allDirectives[i]; + // If literal, then add value as a literal expression, or escape it var normalizedValue = directiveInfo.literal ? directiveInfo.value : JSON.stringify(directiveInfo.value); generatedObject += '"' + directiveInfo.name + '": ' + normalizedValue + ', '; } + // Close object generatedObject = generatedObject.slice(0, -2) + "}"; } - // Close the generated object + // Close the final generated object generatedObject += "}"; return generatedObject; }; @@ -1296,15 +1310,20 @@ * @return {String} generated code */ var generateEventListeners = function (listeners) { + // If no listeners, return empty object if (Object.keys(listeners).length === 0) { return "{}"; } + + // Begin object var generatedObject = "{"; + // Generate an array for all listeners for (var type in listeners) { generatedObject += '"' + type + '": [' + generateArray(listeners[type]) + '], '; } + // Close object generatedObject = generatedObject.slice(0, -2) + "}"; return generatedObject; @@ -1316,8 +1335,10 @@ * @return {String} generated code */ var generateMeta = function (meta) { + // Begin generated object var generatedObject = "{"; + // Generate all metadata for (var key in meta) { if (key === 'eventListeners') { generatedObject += '"' + key + '": ' + generateEventListeners(meta[key]) + ', '; @@ -1326,6 +1347,7 @@ } } + // Close object generatedObject = generatedObject.slice(0, -2) + "}"; return generatedObject; @@ -1337,12 +1359,15 @@ * @return {String} generated array */ var generateArray = function (arr) { + // Begin array var generatedArray = ""; + // Generate all items (literal expressions) for (var i = 0; i < arr.length; i++) { generatedArray += arr[i] + ', '; } + // Close array generatedArray = generatedArray.slice(0, -2); return generatedArray; @@ -1362,12 +1387,12 @@ call += generateProps(vnode, parentVNode) + ", "; // Generate code for children recursively here (in case modified by special directives) - var children = vnode.children.map(function (item) { - return generateEl(item, vnode); + var children = vnode.children.map(function (vchild) { + return generateEl(vchild, vnode); }); // If the "shouldRender" flag is not present, ensure node will be updated - if (vnode.meta.shouldRender && parentVNode) { + if (vnode.meta.shouldRender === true && parentVNode !== undefined) { parentVNode.meta.shouldRender = true; } @@ -1375,13 +1400,16 @@ call += generateMeta(vnode.meta); // Generate Code for Children - if (children.length) { - if (vnode.deep) { + if (children.length !== 0) { + if (vnode.deep === true) { + // If deep, flatten it in the code call += ', [].concat.apply([], [' + generateArray(children) + '])'; } else { + // Not deep, generate a shallow array call += ', [' + generateArray(children) + ']'; } } else { + // No children, empty array call += ", []"; } @@ -1390,19 +1418,17 @@ return call; }; - var generateEl = function (el, parentEl) { + var generateEl = function (vnode, parentVNode) { var code = ""; - if (typeof el === "string") { + if (typeof vnode === "string") { // Escape newlines and double quotes, and compile the string - var escapedString = escapeString(el); + var escapedString = escapeString(vnode); var compiledText = compileTemplate(escapedString, true); var textMeta = defaultMetadata(); if (escapedString !== compiledText) { - if (parentEl) { - parentEl.meta.shouldRender = true; - } + parentVNode.meta.shouldRender = true; textMeta.shouldRender = true; } @@ -1411,38 +1437,38 @@ // Recursively generate code for children // Generate Metadata if not Already - if (!el.meta) { - el.meta = defaultMetadata(); + if (!vnode.meta) { + vnode.meta = defaultMetadata(); } // Detect SVG Element - if (el.isSVG) { - el.meta.isSVG = true; + if (vnode.isSVG) { + vnode.meta.isSVG = true; } // Setup Nested Attributes within Properties - el.props = { - attrs: el.props + vnode.props = { + attrs: vnode.props }; // Create a Call for the Element, or Register a Slot - var slotNameAttr = el.props.attrs.name; var compiledCode = ""; - if (el.type === "slot") { - if (parentEl) { - parentEl.meta.shouldRender = true; - parentEl.deep = true; - } + + if (vnode.type === "slot") { + parentVNode.meta.shouldRender = true; + parentVNode.deep = true; + + var slotNameAttr = vnode.props.attrs.name; compiledCode = 'instance.$slots[\'' + (slotNameAttr && slotNameAttr.value || "default") + '\']'; } else { - compiledCode = createCall(el, parentEl); + compiledCode = createCall(vnode, parentVNode); } // Check for Special Directives that change the code after generation and run them - if (el.specialDirectivesAfter) { - for (var specialDirectiveAfterInfo in el.specialDirectivesAfter) { - var specialDirectiveAfter = el.specialDirectivesAfter[specialDirectiveAfterInfo]; - compiledCode = specialDirectives[specialDirectiveAfter.name].afterGenerate(specialDirectiveAfter.value, specialDirectiveAfter.meta, compiledCode, el); + if (vnode.specialDirectivesAfter !== undefined) { + for (var specialDirectiveAfterInfo in vnode.specialDirectivesAfter) { + var specialDirectiveAfter = vnode.specialDirectivesAfter[specialDirectiveAfterInfo]; + compiledCode = specialDirectives[specialDirectiveAfter.name].afterGenerate(specialDirectiveAfter.value, specialDirectiveAfter.meta, compiledCode, vnode); } } code += compiledCode; diff --git a/dist/moon.min.js b/dist/moon.min.js index 06617038..31c3677f 100644 --- a/dist/moon.min.js +++ b/dist/moon.min.js @@ -4,4 +4,4 @@ * Released under the MIT License * http://moonjs.ga */ -!function(e,t){"object"==typeof module&&module.exports?module.exports=t():e.Moon=t()}(this,function(){"use strict";function e(e){this.instance=e,this.cache={},this.signals={},this.dep={target:null,map:{}}}function t(t){this.$opts=t||{},this.$id=s++,this.$name=this.$opts.name||"root",this.$data=this.$opts.data||{},this.$render=this.$opts.render||$,this.$hooks=this.$opts.hooks||{},this.$methods=this.$opts.methods||{},this.$events={},this.$dom={},this.$observer=new e(this),this.$destroyed=!1,this.$initialRender=!0,this.$queued=!1,this.$opts.computed&&a(this,this.$opts.computed),this.init()}var r={},n={},i={},o={stop:"event.stopPropagation();",prevent:"event.preventDefault();",ctrl:"if(!event.ctrlKey) {return;};",shift:"if(!event.shiftKey) {return;};",alt:"if(!event.altKey) {return;};",enter:"if(event.keyCode !== 13) {return;};"},s=0,a=function(e,t){for(var r in t)!function(r){e.$observer.observe(r);var n={get:function(){var n=null;return e.$observer.cache[r]?n=e.$observer.cache[r]:(e.$observer.dep.target=r,n=t[r].get.call(e),e.$observer.dep.target=null,e.$observer.cache[r]=n),n}};t[r].set&&(n.set=function(n){return t[r].set.call(e,n)}),Object.defineProperty(e.$data,r,n)}(r)};e.prototype.observe=function(e){var t=this;this.signals[e]=function(){t.cache[e]=null}},e.prototype.notify=function(e){if(this.dep.map[e])for(var t=0;ta?s:a,c=0;c",e.current);if(n===-1)return e.tokens.push({type:"comment",value:t.slice(e.current)}),void(e.current=r);e.tokens.push({type:"comment",value:t.slice(e.current,n)}),e.current=n+3},V=function(e){var t=e.input,r=(t.length,"/"===t.charAt(e.current+1));e.current+=r?2:1;var n=H(e);q(n,e);var i="/"===t.charAt(e.current);e.current+=i?2:1,(r||i)&&(n.close=!0)},H=function(e){for(var t=e.input,r=t.length,n=e.current,i="";n"===o||" "===o)break;i+=o,n++}var s={type:"tag",value:i};return e.tokens.push(s),e.current=n,s},q=function(e,t){for(var r=t.input,n=r.length,i=t.current,o=r.charAt(i),s=r.charAt(i+1),a=function(){i++,o=r.charAt(i),s=r.charAt(i+1)},u={};i"!==o&&("/"!==o||">"!==s);)if(" "!==o){for(var p="",c=!1;i"===o||"/"===o||">"===s){c=!0;break}p+=o,a()}var l={name:p,value:"",meta:{}};if(c)u[p]=l;else{a();var f=" ";for("'"!==o&&'"'!==o||(f=o,a());i1&&(a=u.shift(),s=u.join("(").slice(0,-1));var p="";n.shift();for(var c=0;ca?s:a,p=0;p",e.current);if(n===-1)return e.tokens.push({type:"comment",value:t.slice(e.current)}),void(e.current=r);e.tokens.push({type:"comment",value:t.slice(e.current,n)}),e.current=n+3},V=function(e){var t=e.input,r=(t.length,"/"===t.charAt(e.current+1));e.current+=r?2:1;var n=H(e);q(n,e);var i="/"===t.charAt(e.current);e.current+=i?2:1,(r||i)&&(n.close=!0)},H=function(e){for(var t=e.input,r=t.length,n=e.current,i="";n"===o||" "===o)break;i+=o,n++}var s={type:"tag",value:i};return e.tokens.push(s),e.current=n,s},q=function(e,t){for(var r=t.input,n=r.length,i=t.current,o=r.charAt(i),s=r.charAt(i+1),a=function(){i++,o=r.charAt(i),s=r.charAt(i+1)},u={};i"!==o&&("/"!==o||">"!==s);)if(" "!==o){for(var l="",p=!1;i"===o||"/"===o||">"===s){p=!0;break}l+=o,a()}var c={name:l,value:"",meta:{}};if(p)u[l]=c;else{a();var f=" ";for("'"!==o&&'"'!==o||(f=o,a());i1&&(a=u.shift(),s=u.join("(").slice(0,-1));var l="";n.shift();for(var p=0;p