Skip to content

Commit

Permalink
add events system + #if/#else
Browse files Browse the repository at this point in the history
  • Loading branch information
kbrsh committed May 27, 2018
1 parent e171bf5 commit 83b1823
Show file tree
Hide file tree
Showing 11 changed files with 223 additions and 163 deletions.
192 changes: 116 additions & 76 deletions dist/moon.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,26 @@
var locals = ["NaN", "event", "false", "in", "m", "null", "this", "true", "typeof", "undefined"];

var parseTemplate = function (expression, dependencies) {
var info, dynamic = false;
var dynamic = false;

while ((info = expressionRE.exec(expression)) !== null) {
var name = info[1];
if (name !== undefined && locals.indexOf(name) === -1 && name[0] !== "$") {
expression = expression.replace(expressionRE, function(match, name) {
if (name === undefined || locals.indexOf(name) !== -1 || name[0] === "$") {
return match;
} else {
dynamic = true;

if (dependencies.indexOf(name) === -1) {
dependencies.push(name);
}

return ("data." + name);
}
}
});

return dynamic;
return {
expression: expression,
dynamic: dynamic
};
};

var config = {
Expand Down Expand Up @@ -63,7 +69,7 @@
char = input[index];

if (char === "/" || char === ">" || whitespaceRE.test(char)) {
value = key;
value = "";
break;
} else if (char === "=") {
index += 1;
Expand Down Expand Up @@ -104,11 +110,12 @@
}
}

var template = parseTemplate(value, dependencies);
attributes.push({
key: key,
value: value,
value: template.expression,
expression: expression,
dynamic: expression && parseTemplate(value, dependencies)
dynamic: expression && template.dynamic
});
}
}
Expand Down Expand Up @@ -163,7 +170,7 @@
if (element.type[0] !== "#") {
element.index = stack[0].nextIndex++;
}

stack[stack.length - 1].children.push(element);

index += 2;
Expand Down Expand Up @@ -275,13 +282,14 @@
}
}

var template = parseTemplate(expression, dependencies);
stack[stack.length - 1].children.push({
type: "#text",
attributes: [{
key: "",
value: expression,
value: template.expression,
expression: true,
dynamic: parseTemplate(expression, dependencies)
dynamic: template.dynamic
}],
children: []
});
Expand Down Expand Up @@ -359,6 +367,26 @@

var insertBefore = function (element, reference, parent) { return ("m.ib(" + (getElement(element)) + "," + (getElement(reference)) + "," + (getElement(parent)) + ");"); };

var generateDestroy = function (element, parent, root) {
switch (element.type) {
case "#if": {
return removeChild(element.ifReference, parent.index) + "if(" + (getElement(element.ifState)) + "===1){" + (getElement(element.elseDestroy)) + "();}";
}
case "#else": {
return ("else{" + (getElement(element.ifDestroy)) + "();}");
}
case "#comment": {
return removeChild(element.commentElement, parent.index);
}
case "#text": {
return removeChild(element.textElement, parent.index);
}
default: {
return removeChild(element.index, parent.index);
}
}
};

var generateMount = function (element, parent, insert) { return insert === undefined ? appendChild(element, parent) : insertBefore(element, insert, parent); };

var generateCreate = function (element, parent, root, insert) {
Expand All @@ -370,46 +398,63 @@

element.ifReference = root.nextIndex++;
element.ifState = root.nextIndex++;
element.ifCreate = generateCreate(element.children[0], parent, root, element.ifReference);
element.ifCreate = root.nextIndex++;
element.elseDestroy = root.nextIndex++;

if (nextSibling !== undefined && nextSibling.type === "#else") {
nextSibling.ifState = element.ifState;
nextSibling.ifReference = element.ifReference;
nextSibling.elseCreate = root.nextIndex++;
nextSibling.ifDestroy = root.nextIndex++;
} else {
siblings.splice(nextSiblingIndex, 0, {
nextSibling = {
type: "#else",
attributes: [],
children: [{
type: "#comment",
attributes: [],
children: []
}],
children: [],
ifState: element.ifState,
ifReference: element.ifReference
});
elseCreate: root.nextIndex++,
ifDestroy: root.nextIndex++
};

siblings.splice(nextSiblingIndex, 0, nextSibling);
}

return setElement(element.ifReference, createComment()) + generateMount(element.ifReference, parent.index, insert);
var ifCreate = "";
var ifDestroy = "";
var elseCreate = "";
var elseDestroy = "";

var elementChildren = element.children;
for (var i = 0; i < elementChildren.length; i++) {
var child = elementChildren[i];
ifCreate += generateCreate(child, parent, root, element.ifReference);
ifDestroy += generateDestroy(child, parent, root);
}

var nextSiblingChildren = nextSibling.children;
for (var i$1 = 0; i$1 < nextSiblingChildren.length; i$1++) {
var child$1 = nextSiblingChildren[i$1];
elseCreate += generateCreate(child$1, parent, root, element.ifReference);
elseDestroy += generateDestroy(child$1, parent, root);
}

return setElement(element.ifReference, createComment()) + generateMount(element.ifReference, parent.index, insert) + setElement(element.ifCreate, ("function(){" + ifCreate + "};")) + setElement(nextSibling.ifDestroy, ("function(){" + ifDestroy + "};")) + setElement(nextSibling.elseCreate, ("function(){" + elseCreate + "};")) + setElement(element.elseDestroy, ("function(){" + elseDestroy + "};")) + "if(" + (attributeValue(element.attributes[0])) + "){" + (getElement(element.ifCreate)) + "();" + (setElement(element.ifState, "0;")) + "}";
}
case "#else": {
element.ifCreate = generateCreate(element.children[0], parent, root, element.ifReference);
return "";
return ("else{" + (getElement(element.elseCreate)) + "();" + (setElement(element.ifState, "1;")) + "}");
}
case "#comment": {
element.commentElement = root.nextIndex++;
return setElement(element.commentElement, createComment());
return setElement(element.commentElement, createComment()) + generateMount(element.commentElement, parent.index, insert);
}
case "#text": {
var textAttribute = element.attributes[0];
element.textElement = root.nextIndex++;
return setElement(element.textElement, createTextNode(textAttribute.dynamic ? "\"\"" : attributeValue(textAttribute))) + generateMount(element.textElement, parent.index, insert);
return setElement(element.textElement, createTextNode(attributeValue(textAttribute))) + generateMount(element.textElement, parent.index, insert);
}
default: {
return setElement(element.index, createElement(element.type)) + mapReduce(element.attributes, function (attribute) {
if (attribute.key[0] === "@") {
return addEventListener(element.index, attribute);
} else if (attribute.dynamic) {
return "";
} else {
return setAttribute(element.index, attribute);
}
Expand All @@ -418,36 +463,17 @@
}
};

var generateDestroy = function (element, parent, root) {
var generateUpdate = function (element, parent, root) {
switch (element.type) {
case "#if": {
return removeChild(element.ifReference, parent.index) + generateDestroy(element.children[0], parent, root);
}
case "#comment": {
return removeChild(element.commentElement, parent.index);
return ("if(" + (attributeValue(element.attributes[0])) + "){if(" + (getElement(element.ifState)) + "===0){" + (mapReduce(element.children, function (child) { return generateUpdate(child, parent, root); })) + "}else{" + (getElement(element.elseDestroy)) + "();" + (getElement(element.ifCreate)) + "();" + (setElement(element.ifState, "0;")) + "}}");
}
case "#text": {
return removeChild(element.textElement, parent.index);
}
default: {
return removeChild(element.index, parent.index);
case "#else": {
return ("else{if(" + (getElement(element.ifState)) + "===1){" + (mapReduce(element.children, function (child) { return generateUpdate(child, parent, root); })) + "}else{" + (getElement(element.ifDestroy)) + "();" + (getElement(element.elseCreate)) + "();" + (setElement(element.ifState, "1;")) + "}}");
}
}
};

var generateUpdate = function (element, parent, root) {
switch (element.type) {
case "#text": {
var textAttribute = element.attributes[0];
return textAttribute.dynamic ? setTextContent(element.index, textAttribute.value) : "";
}
case "#if": {
var ifChild = element.children[0];
return ("\n if (" + (attributeValue(element.attributes[0])) + ") {\n if (" + (getElement(element.ifState)) + " === 0) {\n " + (generateUpdate(ifChild, parent, root)) + "\n } else {\n " + (generateDestroy(ifChild, parent, root)) + "\n " + (element.ifCreate) + "\n " + (setElement(element.ifState, "0")) + "\n }\n }\n ");
}
case "#else": {
var ifChild$1 = element.children[0];
return ("\n else {\n if (" + (getElement(element.ifState)) + " === 1) {\n " + (generateUpdate(ifChild$1, parent, root)) + "\n } else {\n " + (generateDestroy(ifChild$1, parent, root)) + "\n " + (element.ifCreate) + "\n " + (setElement(element.ifState, "1")) + "\n }\n }\n ");
return textAttribute.dynamic ? setTextContent(element.textElement, textAttribute.value) : "";
}
default: {
return mapReduce(element.attributes, function (attribute) {
Expand All @@ -462,8 +488,7 @@
};

var generate = function (tree) {
var prelude = mapReduce(tree.dependencies, function (dependency) { return ("var " + dependency + "=this.data." + dependency + ";"); });
return new Function(("return [function(m){this.m[0]=m;m=this.m;" + prelude + (mapReduce(tree.children, function (child) { return generateCreate(child, tree, tree); })) + "},function(){var m=this.m;" + prelude + (mapReduce(tree.children, function (child) { return generateUpdate(child, tree, tree); })) + "},function(){var m=this.m;" + (mapReduce(tree.children, function (child) { return generateDestroy(child, tree, tree); })) + "m=[m[0]];}];"))();
return new Function(("return [function(m){this.m[0]=m;m=this.m;var data=this.data;" + (mapReduce(tree.children, function (child) { return generateCreate(child, tree, tree); })) + "},function(){var m=this.m;var data=this.data;" + (mapReduce(tree.children, function (child) { return generateUpdate(child, tree, tree); })) + "},function(){var m=this.m;" + (mapReduce(tree.children, function (child) { return generateDestroy(child, tree, tree); })) + "this.m=[m[0]];}];"))();
};

var compile = function (input) {
Expand Down Expand Up @@ -553,35 +578,37 @@
};

var on = function(type, handler) {
var data = this.data;
var handlers = data[type];
var events = this.events;
var handlers = events[type];

if (handlers === undefined) {
data[type] = handler;
events[type] = handler;
} else if (typeof handlers === "function") {
data[type] = [handlers, handler];
events[type] = [handlers, handler];
} else {
handlers.push(handler);
}
};

var off = function(type, handler) {
if (handler === undefined) {
this.data[type] = [];
if (type === undefined) {
this.events = {};
} else if (handler === undefined) {
this.events[type] = [];
} else {
var data = this.data;
var handlers = data[type];
var events = this.events;
var handlers = events[type];

if (typeof handlers === "function") {
data[type] = undefined;
events[type] = undefined;
} else {
handlers.splice(handlers.indexOf(handler), 1);
}
}
};

var emit = function(type, data) {
var handlers = this.data[type];
var handlers = this.events[type];

if (handlers !== undefined) {
if (typeof handlers === "function") {
Expand All @@ -605,9 +632,23 @@
this.m = m();

var data = this.data = options.data();
var actions = options.actions;
for (var action in actions) {
data[action] = actions[action].bind(this$1);
for (var key in data) {
var value = data[key];
if (typeof value === "function") {
data[key] = value.bind(this$1);
}
}

var events = this.events = options.events;
for (var type in events) {
var handlers = events[type];
if (typeof handlers === "function") {
events[type] = handlers.bind(this$1);
} else {
for (var i = 0; i < handlers.length; i++) {
handlers[i] = handlers[i].bind(this$1);
}
}
}

this.create = create;
Expand Down Expand Up @@ -639,16 +680,15 @@
options.data = function () { return data; };
}

var actions = options.actions;
if (actions === undefined) {
options.actions = {};
var events = options.events;
if (events === undefined) {
options.events = {};
}

var instanceComponent = component("#m", options);
var instanceComponent = component("", options);
var instance = new instanceComponent();

instance.create(root);
instance.update();

return instance;
}
Expand All @@ -666,9 +706,9 @@
};
}

var actions = options.actions;
if (actions === undefined) {
options.actions = {};
var events = options.events;
if (events === undefined) {
options.events = {};
}

components[name] = component(name, options);
Expand Down
Loading

0 comments on commit 83b1823

Please sign in to comment.