Comparing version 1.0.1 to 1.0.2
var Visitor = require('./visitor'); | ||
var TextParser = require('./parsers/text'); | ||
var VariableParser = require('./parsers/variable'); | ||
var ForeachParser = require('./parsers/foreach'); | ||
@@ -46,7 +47,10 @@ function Compiler(name, dom) { | ||
if (as_module) { | ||
code = 'module.exports = {' + code + '};\n'; | ||
code = 'module.exports = function (monkberry, document) {\n' | ||
+ indent('var filters = monkberry.filters;', undefined, true) + '\n' | ||
+ indent('return {\n' + code + '};', undefined, true) + '\n' | ||
+ '};\n' | ||
} else { | ||
code = '(function (monkberry, filters, document, undefined) {\n ' | ||
+ indent('monkberry.mount({\n' + code + '});') | ||
+ '\n})(monkberry, monkberry.filters, window.document, void 0);\n'; | ||
+ indent('monkberry.mount({\n' + code + '});') | ||
+ '\n})(monkberry, monkberry.filters, window.document, void 0);\n'; | ||
} | ||
@@ -73,14 +77,17 @@ return code; | ||
code += ' // Create view\n'; | ||
code += ' var view = monkberry.view();\n'; | ||
code += '\n'; | ||
if (size(this.setters) > 0) { | ||
code += ' // Create setters\n'; | ||
code += ' // Setters functions\n'; | ||
code += ' var set = {\n'; | ||
code += ' ' + indent(this.compileSetters(), 4) + '\n'; | ||
code += ' };\n'; | ||
code += '\n'; | ||
} | ||
code += ' // Create view\n'; | ||
code += ' var view = {\n'; | ||
code += ' update: function (data) {\n'; | ||
code += ' ' + indent(this.compileUpdate(), 6) + '\n'; | ||
code += ' }\n'; | ||
code += ' // Update function\n'; | ||
code += ' view.update = function (data) {\n'; | ||
code += ' ' + indent(this.compileUpdate(), 4) + '\n'; | ||
code += ' };\n'; | ||
@@ -125,5 +132,4 @@ code += '\n'; | ||
if (size(this.setters) > 0) { | ||
code.push('var t'); | ||
Object.keys(this.setters).forEach(function (varName) { | ||
code.push("(t = data." + varName + ") !== undefined && set." + varName + "(t)"); | ||
code.push("data." + varName + " !== undefined && set." + varName + "(data." + varName + ")"); | ||
}); | ||
@@ -170,2 +176,22 @@ } | ||
Compiler.prototype.svgNode = function (node) { | ||
var nodeName = node.name + this.uniqid(); | ||
node.nodeName = nodeName; | ||
this.declarations.push(nodeName + " = document.createElementNS('http://www.w3.org/2000/svg', '" + node.name + "')"); | ||
if (node.name == 'svg') { | ||
this.construct.push(nodeName + ".setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xlink', 'http://www.w3.org/1999/xlink');"); | ||
} | ||
var children = this.visit(node.children); | ||
for (var child of children) { | ||
this.construct.push(nodeName + ".appendChild(" + child + ");"); | ||
} | ||
this.compileAttributes(nodeName, node.attribs); | ||
return nodeName; | ||
}; | ||
Compiler.prototype.compileAttributes = function (nodeName, attributes) { | ||
@@ -252,3 +278,3 @@ var _this = this; | ||
"if (data." + variable.name + " !== undefined) \n" + | ||
" monkberry.iftest(view, " + | ||
" monkberry.insert(view, " + | ||
placeholder + ", " + | ||
@@ -270,4 +296,16 @@ childrenName + ", '" + | ||
var variable = new VariableParser(node.attribs.each); | ||
var foreach = new ForeachParser(node.attribs.each); | ||
var variable = foreach.variable; | ||
var options = null; | ||
if (foreach.valueName) { | ||
options = { | ||
valueName: foreach.valueName | ||
}; | ||
if (foreach.keyName) { | ||
options.keyName = foreach.keyName; | ||
} | ||
} | ||
var templateName; | ||
@@ -291,3 +329,3 @@ if (node.attribs.name) { | ||
this.subTemplates.push(new Compiler(templateName, node.children)); | ||
this.declarations.push(childrenName + " = {}"); | ||
this.declarations.push(childrenName + " = monkberry.map()"); | ||
this.variables[variable.name] = variable; | ||
@@ -300,2 +338,3 @@ this.addSetters(variable.name, | ||
variable.toString('value') + | ||
(options !== null ? ', ' + esc(options) : '') + | ||
")" | ||
@@ -326,3 +365,3 @@ ); | ||
this.controlStructures.push( | ||
"monkberry.iftest(view, " + | ||
"monkberry.insert(view, " + | ||
placeholder + ", " + | ||
@@ -329,0 +368,0 @@ childrenName + ", '" + |
var htmlparser = require('htmlparser2'); | ||
var drawTree = require('asciitree'); | ||
var through = require('through'); | ||
var path = require('path'); | ||
var fs = require('fs'); | ||
var Compiler = require('./compiler'); | ||
@@ -28,28 +25,2 @@ | ||
Monkberry.monkberrify = function (file) { | ||
if (/\.(monk|html)$/.test(file)) { | ||
var data = '', stream = through(write, end); | ||
return stream; | ||
} else { | ||
return through(); | ||
} | ||
function write(buf, enc, next) { | ||
var name = path.parse(file).name; | ||
console.log(file); | ||
var text = fs.readFileSync(file, {encoding: 'utf8'}); | ||
Monkberry(name, text, { | ||
normalizeWhitespace: true | ||
}, function (compiler) { | ||
data += compiler.compile(true); | ||
}); | ||
} | ||
function end() { | ||
stream.queue(data); | ||
stream.queue(null); | ||
} | ||
}; | ||
module.exports = Monkberry; |
@@ -32,2 +32,4 @@ function Visitor(callback) { | ||
push(this.callback.tagNode(node)); | ||
} else if (SVGElements.indexOf(node.name) != -1) { | ||
push(this.callback.svgNode(node)); | ||
} else if (node.name === 'if') { | ||
@@ -34,0 +36,0 @@ push(this.callback.ifNode(node)); |
255
monkberry.js
@@ -1,2 +0,2 @@ | ||
(function () { | ||
(function (document) { | ||
function Monkberry() { | ||
@@ -9,9 +9,9 @@ this.pool = new Pool(); | ||
Monkberry.prototype.foreach = function (parent, node, children, template, data) { | ||
var i, j, len, childrenSize = size(children); | ||
Monkberry.prototype.foreach = function (parent, node, map, template, data, options) { | ||
var i, j, len, childrenSize = map.length; | ||
len = childrenSize - data.length; | ||
for (i in children) if (children.hasOwnProperty(i)) { | ||
for (i in map.items) { | ||
if (len-- > 0) { | ||
children[i].remove(); | ||
map.items[i].remove(); | ||
} else { | ||
@@ -23,25 +23,36 @@ break; | ||
j = 0; | ||
for (i in children) if (children.hasOwnProperty(i)) { | ||
children[i].update(data[j++]); | ||
for (i in map.items) { | ||
map.items[i].update(forData(data[j], j, options)); | ||
j++; | ||
} | ||
for (j = childrenSize, len = data.length; j < len; j++) { | ||
// Render new view | ||
var view = this.render(template); | ||
// Set view hierarchy | ||
view.parent = parent; | ||
parent.children.push(view); | ||
view.appendTo(node); | ||
view.update(data[j]); | ||
i = push(children, view); | ||
parent.nested.push(view); | ||
var viewRemove = view.remove; | ||
view.remove = (function (i, viewRemove) { | ||
// Add nodes DOM | ||
if (node.nodeType == 8) { | ||
view.insertBefore(node); | ||
} else { | ||
view.appendTo(node); | ||
} | ||
// Set view data (note what it must be after adding nodes to DOM) | ||
view.update(forData(data[j], j, options)); | ||
// Remember to remove from children map on view remove | ||
i = map.push(view); | ||
view.onRemove = (function (i) { | ||
return function () { | ||
viewRemove(); | ||
remove(children, i); | ||
map.remove(i); | ||
}; | ||
})(i, viewRemove); | ||
})(i); | ||
} | ||
}; | ||
Monkberry.prototype.iftest = function (parent, node, child/*.ref*/, template, data, test) { | ||
Monkberry.prototype.insert = function (parent, node, child/*.ref*/, template, data, test) { | ||
if (child.ref) { | ||
@@ -55,12 +66,22 @@ if (test) { | ||
} else if (test) { | ||
// Render new view | ||
var view = this.render(template); | ||
// Set view hierarchy | ||
view.parent = parent; | ||
parent.children.push(view); | ||
view.appendTo(node); | ||
parent.nested.push(view); | ||
// Add nodes DOM | ||
if (node.nodeType == 8) { | ||
view.insertBefore(node); | ||
} else { | ||
view.appendTo(node); | ||
} | ||
// Set view data (note what it must be after adding nodes to DOM) | ||
view.update(data); | ||
// Remember to remove from children map on view remove | ||
child.ref = view; | ||
var viewRemove = view.remove; | ||
view.remove = function () { | ||
viewRemove(); | ||
view.onRemove = function () { | ||
child.ref = null; | ||
@@ -75,6 +96,8 @@ }; | ||
if (this.templates[name]) { | ||
var view, self = this; | ||
var view; | ||
if (no_cache) { | ||
view = this.templates[name](); | ||
view.name = name; | ||
view.pool = this.pool; | ||
} else { | ||
@@ -84,54 +107,7 @@ view = this.pool.pull(name); | ||
view = this.templates[name](); | ||
view.name = name; | ||
view.pool = this.pool; | ||
} | ||
} | ||
view.parent = null; | ||
view.children = []; | ||
view.appendTo = function (toNode) { | ||
for (var i = 0, len = view.nodes.length; i < len; i++) { | ||
if (toNode.nodeType == 8) { | ||
if (toNode.parentNode) { | ||
toNode.parentNode.insertBefore(view.nodes[i], toNode); | ||
} else { | ||
throw new Error("Can not insert child view into parent node." + | ||
"You need append your view first and then update."); | ||
} | ||
} else { | ||
toNode.appendChild(view.nodes[i]); | ||
} | ||
} | ||
}; | ||
view.getDom = function (toNode) { | ||
if (view.nodes.length == 1) { | ||
return view.nodes[0]; | ||
} else { | ||
var fragment = document.createDocumentFragment(); | ||
for (var i = 0, len = view.nodes.length; i < len; i++) { | ||
fragment.appendChild(view.nodes[i]); | ||
} | ||
return fragment; | ||
} | ||
}; | ||
view.remove = function () { | ||
// Remove appended nodes | ||
var i = view.nodes.length; | ||
while (i--) { | ||
view.nodes[i].parentNode.removeChild(view.nodes[i]); | ||
} | ||
// Remove all children views | ||
i = view.children.length; | ||
while (i--) { | ||
view.children[i].remove(); | ||
} | ||
// Remove this view from parent views children. | ||
if (view.parent) { | ||
i = view.parent.children.indexOf(view); | ||
view.parent.children.splice(i, 1); | ||
} | ||
self.pool.push(name, view); | ||
}; | ||
if (values !== undefined) { | ||
@@ -161,2 +137,7 @@ view.update(values); | ||
var _this = this; | ||
if (typeof templates === 'function') { | ||
templates = templates(this, document); | ||
} | ||
Object.keys(templates).forEach(function (name) { | ||
@@ -167,2 +148,70 @@ _this.templates[name] = templates[name]; | ||
Monkberry.prototype.view = function () { | ||
return new View; | ||
}; | ||
Monkberry.prototype.map = function () { | ||
return new Map; | ||
}; | ||
function View() { | ||
this.name = ''; // Name of template | ||
this.parent = null; // Parent view | ||
this.nested = []; // Nested views | ||
this.nodes = []; // Root DOM nodes | ||
} | ||
View.prototype.appendTo = function (toNode) { | ||
for (var i = 0, len = this.nodes.length; i < len; i++) { | ||
toNode.appendChild(this.nodes[i]); | ||
} | ||
}; | ||
View.prototype.insertBefore = function (toNode) { | ||
for (var i = 0, len = this.nodes.length; i < len; i++) { | ||
if (toNode.parentNode) { | ||
toNode.parentNode.insertBefore(this.nodes[i], toNode); | ||
} else { | ||
throw new Error("Can not insert child view into parent node." + | ||
"You need append your view first and then update."); | ||
} | ||
} | ||
}; | ||
View.prototype.dom = function (toNode) { | ||
if (this.nodes.length == 1) { | ||
return this.nodes[0]; | ||
} else { | ||
var fragment = document.createDocumentFragment(); | ||
for (var i = 0, len = this.nodes.length; i < len; i++) { | ||
fragment.appendChild(this.nodes[i]); | ||
} | ||
return fragment; | ||
} | ||
}; | ||
View.prototype.remove = function () { | ||
// Remove appended nodes | ||
var i = this.nodes.length; | ||
while (i--) { | ||
this.nodes[i].parentNode.removeChild(this.nodes[i]); | ||
} | ||
// Remove self from parent's children map | ||
if (this.onRemove) { | ||
this.onRemove(); | ||
} | ||
// Remove all nested views | ||
i = this.nested.length; | ||
while (i--) { | ||
this.nested[i].remove(); | ||
} | ||
// Remove this view from parent's nested views. | ||
if (this.parent) { | ||
i = this.parent.nested.indexOf(this); | ||
this.parent.nested.splice(i, 1); | ||
} | ||
// Store view in pool for reuse | ||
this.pool.push(this.name, this); | ||
}; | ||
function Pool() { | ||
@@ -187,31 +236,43 @@ this.store = {}; | ||
// Helper functions | ||
// Helper functions for working with "map". | ||
function max(map) { | ||
var maximum = 0; | ||
for (var i in map) if (map.hasOwnProperty(i)) { | ||
i = parseInt(i); | ||
if (i > maximum) { | ||
maximum = i; | ||
} | ||
} | ||
return parseInt(maximum); | ||
function Map() { | ||
this.items = Object.create(null); | ||
this.length = 0; | ||
this.next = 0; | ||
} | ||
function push(map, element) { | ||
var maximum = max(map) + 1; | ||
map[maximum] = element; | ||
return maximum; | ||
} | ||
Map.prototype.push = function (element) { | ||
this.items[this.next] = element; | ||
this.length += 1; | ||
this.next += 1; | ||
return this.next - 1; | ||
}; | ||
function remove(map, i) { | ||
delete map[i]; | ||
} | ||
Map.prototype.remove = function (i) { | ||
if (i in this.items) { | ||
delete this.items[i]; | ||
this.length -= 1; | ||
} else { | ||
// TODO: Remove this in future, after API stabilization. | ||
throw new Error('You are trying to delete not existing element "' + i + '" form map.'); | ||
} | ||
}; | ||
function size(map) { | ||
var size = 0; | ||
for (var i in map) if (map.hasOwnProperty(i)) { | ||
size++; | ||
/** | ||
* Helper function for working with foreach loops data. | ||
*/ | ||
function forData(data, i, options) { | ||
if (options) { | ||
var newData = {}; | ||
newData[options.valueName] = data; | ||
if (options.keyName) { | ||
newData[options.keyName] = i; | ||
} | ||
return newData; | ||
} else { | ||
return data; | ||
} | ||
return size; | ||
} | ||
@@ -224,2 +285,2 @@ | ||
} | ||
})(); | ||
})(window.document); |
{ | ||
"name": "monkberry", | ||
"version": "1.0.1", | ||
"description": "DOM Template Engine", | ||
"version": "1.0.2", | ||
"description": "JavaScript DOM Template Engine", | ||
"bin": "./bin/monkberry", | ||
"main": "lib/index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
"test": "node_modules/.bin/testem ci -l phantomjs" | ||
}, | ||
@@ -20,3 +20,3 @@ "browser": "./monkberry.js", | ||
], | ||
"author": "Anton Medvedev <anton@elfet.ru>", | ||
"author": "Anton Medvedev <anton@medv.io>", | ||
"license": "MIT", | ||
@@ -28,7 +28,11 @@ "bugs": { | ||
"dependencies": { | ||
"asciitree": "^1.0.0", | ||
"commander": "^2.8.1", | ||
"htmlparser2": "^3.8.3", | ||
"through": "^2.3.7" | ||
}, | ||
"devDependencies": { | ||
"asciitree": "^1.0.0", | ||
"jasmine": "^2.3.2", | ||
"testem": "^0.9.4" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
92337
3
31
0
1
5
0
3
902
- Removedasciitree@^1.0.0
- Removedasciitree@1.0.2(transitive)