@jeefo/template
Advanced tools
Comparing version 0.0.2 to 0.0.3
23
index.js
/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. | ||
* File Name : index.js | ||
* Created at : 2017-08-09 | ||
* Updated at : 2019-06-25 | ||
* Updated at : 2020-06-05 | ||
* Author : jeefo | ||
@@ -19,20 +19,5 @@ * Purpose : | ||
exports.compile = nodes => { | ||
return nodes.map(node => { | ||
const attrs = []; | ||
const element_name = node.name || "div"; | ||
let content = ''; | ||
if (node.id) { | ||
attrs.push(`id="${ node.id }"`); | ||
} | ||
if (node.class_list) { | ||
attrs.push(`class="${ node.class_list.join(' ') }"`); | ||
} | ||
Object.keys(node.attrs).forEach(key => { | ||
attrs.push(`${ key }="${ node.attrs[key] }"`); | ||
}); | ||
return `<${ element_name }${ attrs }>${ content }</${ element_name }>`; | ||
}).join(''); | ||
exports.compile = (source, indent) => { | ||
const nodes = exports.parse(source); | ||
return nodes.map(node => node.toString(indent)).join(indent ? '\n' : ''); | ||
}; |
/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. | ||
* File Name : node_element.js | ||
* Created at : 2017-08-11 | ||
* Updated at : 2019-07-18 | ||
* Updated at : 2020-06-05 | ||
* Author : jeefo | ||
@@ -17,3 +17,6 @@ * Purpose : | ||
/* | ||
const Attributes = require("./tokens/attributes"); | ||
const object_assign = require("@jeefo/utils/object/assign"); | ||
*/ | ||
@@ -23,111 +26,45 @@ //const SELF_CLOSED_TAGS = ["img", "input", "hr", "br", "col"]; | ||
class NodeElement { | ||
constructor (id, token, parent = null) { | ||
this.id = id; | ||
this.name = token.name || "div"; | ||
this.attrs = token.attrs; | ||
this.events = token.events; | ||
this.parent = parent; | ||
this.content = token.content; | ||
this.children = []; | ||
this.class_list = token.class_list; | ||
constructor (token, parent = null) { | ||
this.name = token.name || "div"; | ||
this.attrs = token.attrs; | ||
this.parent = parent; | ||
this.content = token.content; | ||
this.children = []; | ||
} | ||
add_child (node) { | ||
node.parent = this; | ||
this.children.push(node); | ||
} | ||
last_child () { | ||
return this.children[this.children.length - 1]; | ||
} | ||
toString (indentation) { | ||
let attrs = this.attrs.toString(); | ||
if (attrs) { attrs = ` ${attrs}`; } | ||
let content = ''; | ||
//to_html () {} | ||
if (this.content) { | ||
content = this.content; | ||
} else if (this.children.length) { | ||
if (indentation) { | ||
let deep = 1, p = this.parent; | ||
while (p) { | ||
p = p.parent; | ||
deep += 1; | ||
} | ||
const indent = indentation.repeat(deep); | ||
clone (is_deep) { | ||
const node = new NodeElement(this.id, { | ||
name : this.name, | ||
content : this.content, | ||
attrs : this.attrs.clone(), | ||
events : object_assign(this.events), | ||
class_list : this.class_list.concat(), | ||
}, this.parent); | ||
content = this.children.map(n => { | ||
return n.toString(indentation); | ||
}).join(`\n${indent}`); | ||
if (is_deep) { | ||
node.children = this.children.map(child => child.clone(true)); | ||
} else { | ||
node.children = this.children; | ||
content = `\n${indent}${content}\n${indentation.repeat(deep - 1)}`; | ||
} else { | ||
content = this.children.map(n => n.toString()).join(''); | ||
} | ||
} | ||
return node; | ||
return `<${this.name}${attrs}>${content}</${this.name}>`; | ||
} | ||
} | ||
/* | ||
NodeElement.prototype = { | ||
clear : function () { | ||
this.id = null; | ||
this.name = "div"; | ||
this.attrs = new Attributes(); | ||
this.events = new Events(); | ||
this.parent = null; | ||
this.content = null; | ||
this.children = []; | ||
this.class_list = new ClassList(); | ||
}, | ||
clone : function () { | ||
var node = new NodeElement({ | ||
id : this.id || null, | ||
name : this.name, | ||
attrs : this.attrs.clone(), | ||
events : this.events.clone(), | ||
parent : this.parent, | ||
content : this.content || null, | ||
class_list : this.class_list.clone() | ||
}), i = this.children.length; | ||
while (i--) { | ||
node.children[i] = this.children[i].clone(); | ||
node.children[i].parent = node; | ||
} | ||
return node; | ||
}, | ||
compile : function (indent, indentation) { | ||
var attrs = this.attrs.compile(), line_break = indentation ? '\n' : '', content; | ||
if (this.class_list.list.length) { | ||
attrs = ` class="${ this.class_list.list.join(' ') }"${ attrs }`; | ||
} | ||
if (this.id) { | ||
attrs = ` id="${ this.id }"${ attrs }`; | ||
} | ||
if (this.component_id) { | ||
attrs = `${ attrs } jeefo-component-id="${ this.component_id }"`; | ||
} | ||
var name = this.name || "div"; | ||
if (SELF_CLOSED_TAGS.indexOf(this.name) > -1) { | ||
return `<${ name }${ attrs }>`; | ||
} | ||
if (this.content) { | ||
content = this.content; | ||
} else { | ||
var i = this.children.length, child_indent = `${ indent }${ indentation }`; | ||
content = ''; | ||
while (i--) { | ||
content = `${ line_break }${ child_indent }${ this.children[i].compile(child_indent, indentation) }${ content }`; | ||
} | ||
if (content) { | ||
content += `${ line_break }${ indent }`; | ||
} | ||
} | ||
return `<${ name }${ attrs }>${ content }</${ name }>`; | ||
}, | ||
}; | ||
*/ | ||
module.exports = NodeElement; |
{ | ||
"name": "@jeefo/template", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"description": "Part of jeefo framework.", | ||
@@ -28,3 +28,4 @@ "author": { | ||
"devDependencies": { | ||
"@jeefo/publish": "0.0.31" | ||
"@jeefo/publish": "0.0.31", | ||
"@jeefo/utils": "0.0.5" | ||
}, | ||
@@ -31,0 +32,0 @@ "dependencies": { |
/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. | ||
* File Name : parser.js | ||
* Created at : 2017-08-12 | ||
* Updated at : 2019-07-06 | ||
* Updated at : 2020-06-11 | ||
* Author : jeefo | ||
@@ -23,6 +23,7 @@ * Purpose : | ||
const root = new NodeElement(null, {}); | ||
const result = []; | ||
let token = tokenizer.get_next_token(); | ||
let parent_element = root; | ||
let parent_element = null; | ||
let expect_element = true; | ||
let node, last_token; | ||
@@ -33,45 +34,44 @@ | ||
case "Element": | ||
node = new NodeElement(token._id, token, parent_element); | ||
parent_element.add_child(node); | ||
if (expect_element) { | ||
node = new NodeElement(token, parent_element); | ||
if (parent_element) { | ||
parent_element.add_child(node); | ||
} else { | ||
result.push(node); | ||
} | ||
expect_element = false; | ||
} else { | ||
const str = tokenizer.streamer.substring_from_token(token); | ||
throw new Error(`Unexpected element: ${str}`); | ||
} | ||
break; | ||
case "Operator": | ||
switch (token.operator) { | ||
case '^' : | ||
if (parent_element) { | ||
parent_element = parent_element.parent; | ||
} else { | ||
throw new Error("Expected operator"); | ||
} | ||
break; | ||
case '+' : | ||
if (last_token.operator === '>') { | ||
node = new NodeElement(null, {}, parent_element); | ||
parent_element.add_child(node); | ||
} | ||
switch (last_token.operator) { case '+' : case '>' : | ||
node = new NodeElement(null, {}, parent_element); | ||
parent_element.add_child(node); | ||
} | ||
if (expect_element) { | ||
throw new Error("Unexpected operator"); | ||
} | ||
break; | ||
case '>' : | ||
switch (last_token.operator) { | ||
case '+' : | ||
case '>' : | ||
node = new NodeElement(null, {}, parent_element); | ||
parent_element.add_child(node); | ||
parent_element = node; | ||
break; | ||
default: | ||
parent_element = parent_element.last_child(); | ||
} | ||
if (expect_element) { | ||
throw new Error("Unexpected operator"); | ||
} | ||
const arr = parent_element | ||
? parent_element.children : result; | ||
parent_element = arr[arr.length - 1]; | ||
if (parent_element.content) { | ||
throw new Error("Ambiguous children"); | ||
} | ||
break; | ||
case '^' : | ||
if (last_token.operator === '>') { | ||
node = new NodeElement(null, {}, parent_element); | ||
parent_element.add_child(node); | ||
} | ||
if (parent_element.parent) { | ||
parent_element = parent_element.parent; | ||
} else { | ||
throw new Error("No parent element"); | ||
} | ||
break; | ||
default: | ||
throw new Error("Invalid Operator"); | ||
} | ||
expect_element = true; | ||
break; | ||
@@ -84,12 +84,3 @@ } | ||
/* | ||
switch (last_token.operator) { case '+': case '>': | ||
if (! last_token.compiled) { | ||
node = new NodeElement({}, parent_element); | ||
parent_element.children[parent_element.children.length] = node; | ||
} | ||
} | ||
*/ | ||
return root.children; | ||
return result; | ||
}; |
/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. | ||
* File Name : attributes.js | ||
* Created at : 2017-08-14 | ||
* Updated at : 2019-09-10 | ||
* Updated at : 2020-06-04 | ||
* Author : jeefo | ||
@@ -18,69 +18,15 @@ * Purpose : | ||
const array_remove = require("@jeefo/utils/array/remove"); | ||
class Attributes { | ||
constructor () { | ||
this.names = []; | ||
this.values = {}; | ||
get length () { | ||
return Object.keys(this).length; | ||
} | ||
has (name) { | ||
return this.names.includes(name); | ||
toString () { | ||
return Object.keys(this).map(key => { | ||
return this[key] === null ? key : `${key}="${this[key]}"`; | ||
}).join(' '); | ||
} | ||
get (name) { | ||
return this.values[name]; | ||
} | ||
set (name, value) { | ||
if (! this.names.includes(name)) { | ||
this.names.push(name); | ||
} | ||
this.values[name] = value; | ||
} | ||
remove (name) { | ||
array_remove(this.names, name); | ||
} | ||
each (callback) { | ||
const { names, values } = this; | ||
for (let i = 0; i < names.length; ++i) { | ||
callback(names[i], values[names[i]]); | ||
} | ||
} | ||
* [Symbol.iterator] () { | ||
const { names, values } = this; | ||
for (let i = 0; i < names.length; ++i) { | ||
yield [names[i], values[names[i]]]; | ||
} | ||
} | ||
filter (callback) { | ||
const { names, values } = this; | ||
for (let i = 0; i < names.length; ++i) { | ||
if (! callback(names[i], values[names[i]])) { | ||
names.splice(i, 1); | ||
i -= 1; | ||
} | ||
} | ||
} | ||
find (callback) { | ||
const { names, values } = this; | ||
for (let i = 0; i < names.length; ++i) { | ||
if (callback(names[i], values[names[i]])) { | ||
return names[i]; | ||
} | ||
} | ||
} | ||
clone () { | ||
const clone = new Attributes(); | ||
this.names.forEach(name => { | ||
clone.names.push(name); | ||
clone.values[name] = this.values[name]; | ||
}); | ||
return clone; | ||
return Object.assign(new Attributes(), this); | ||
} | ||
@@ -87,0 +33,0 @@ } |
/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. | ||
* File Name : element.js | ||
* Created at : 2017-08-26 | ||
* Updated at : 2019-10-07 | ||
* Updated at : 2020-06-05 | ||
* Author : jeefo | ||
@@ -18,7 +18,6 @@ * Purpose : | ||
const dash_case = require("@jeefo/utils/string/dash_case"); | ||
const Events = require("./events"); | ||
const Attributes = require("./attributes"); | ||
const delimiters = ".,>+^[]()=\"'#{}"; | ||
const special_characters = ".#[(+>^"; | ||
const special_characters = ".#[("; | ||
@@ -30,5 +29,8 @@ const WHITESPACE_REGEX = /\s+/; | ||
let character = streamer.next(); | ||
let character = streamer.next(); | ||
while (character && character !== ')') { | ||
character = streamer.next(); | ||
if (character === '\\') { | ||
streamer.cursor.move_next(); | ||
} | ||
character = streamer.next(true); | ||
} | ||
@@ -71,17 +73,9 @@ | ||
function add_class (class_list, classes) { | ||
classes.split(WHITESPACE_REGEX).filter(c => c).forEach(class_name => { | ||
if (! class_list.includes(class_name)) { | ||
class_list.push(class_name); | ||
} | ||
}); | ||
} | ||
function parse_attrs (streamer, attrs) { | ||
let character = streamer.next(true), key, value; | ||
function parse_attrs (streamer, attrs, events, class_list) { | ||
let character = streamer.next(true), value; | ||
while (character && character !== ']') { | ||
if (character === '(') { | ||
streamer.next(true); | ||
const key = parse_identifier(streamer); | ||
key = parse_identifier(streamer); | ||
character = streamer.next(true); | ||
@@ -101,5 +95,5 @@ | ||
events.add(key, value); | ||
key = `on--${key}`.toLowerCase(); | ||
} else { | ||
const key = dash_case(parse_identifier(streamer)); | ||
key = dash_case(parse_identifier(streamer)); | ||
character = streamer.next(true); | ||
@@ -111,15 +105,11 @@ | ||
character = streamer.next(true); | ||
} else if (key === "class") { | ||
throw new SyntaxError("[JeefoTemplate]: Missing class value."); | ||
} else { | ||
value = undefined; | ||
value = null; | ||
} | ||
if (key === "class") { | ||
add_class(class_list, value); | ||
} else { | ||
attrs.set(key, value); | ||
} | ||
} | ||
if (attrs[key]) { | ||
throw new Error(`Duplicated attribute: ${key}`); | ||
} | ||
attrs[key] = value; | ||
while (character === ',') { | ||
@@ -139,6 +129,4 @@ character = streamer.next(true); | ||
const attrs = new Attributes(); | ||
const events = new Events(); | ||
const class_list = []; | ||
const class_list = new Set(); | ||
let id = null; | ||
let name = null; | ||
@@ -157,14 +145,10 @@ let content = null; | ||
case '.' : | ||
streamer.next(); | ||
const class_name = parse_identifier(streamer).trim(); | ||
if (!class_name) { throw new SyntaxError("Invalid class"); } | ||
class_list.add(class_name); | ||
if (streamer.cursor.has_saved_position()) { | ||
streamer.cursor.commit(); | ||
} | ||
streamer.next(true); | ||
const class_name = parse_identifier(streamer); | ||
if (! class_name) { | ||
throw new SyntaxError("Invalid class"); | ||
} | ||
if (! class_list.includes(class_name)) { | ||
class_list.push(class_name); | ||
} | ||
streamer.cursor.save(); | ||
@@ -174,11 +158,11 @@ current_character = streamer.next(true); | ||
case '#' : | ||
if (attrs.id) { throw new SyntaxError("Invalid syntax"); } | ||
streamer.next(); | ||
const id = parse_identifier(streamer).trim(); | ||
if (! id) { throw new SyntaxError("Invalid id"); } | ||
attrs.id = id; | ||
if (streamer.cursor.has_saved_position()) { | ||
streamer.cursor.commit(); | ||
} | ||
streamer.next(true); | ||
id = parse_identifier(streamer); | ||
if (! id) { | ||
throw new SyntaxError("Invalid id"); | ||
} | ||
streamer.cursor.save(); | ||
@@ -193,7 +177,6 @@ current_character = streamer.next(true); | ||
if (current_character === '[') { | ||
parse_attrs(streamer, attrs); | ||
if (streamer.cursor.has_saved_position()) { | ||
streamer.cursor.commit(); | ||
} | ||
parse_attrs(streamer, attrs, events, class_list); | ||
streamer.cursor.save(); | ||
@@ -203,18 +186,21 @@ current_character = streamer.next(true); | ||
if (current_character && current_character === '(') { | ||
if (current_character === '(') { | ||
content = parse_content(streamer); | ||
streamer.cursor.commit(); | ||
content = parse_content(streamer); | ||
} else if (streamer.cursor.has_saved_position()) { | ||
} else { | ||
streamer.cursor.rollback(); | ||
} | ||
token._id = id; | ||
token.name = name; | ||
token.attrs = attrs; | ||
token.events = events; | ||
token.class_list = class_list; | ||
token.content = content; | ||
token.start = start; | ||
token.end = streamer.clone_cursor_position(); | ||
if (class_list.size) { | ||
attrs.class = [...class_list].concat( | ||
attrs.class ? attrs.class.split(WHITESPACE_REGEX) : [] | ||
).join(' '); | ||
} | ||
token.name = name; | ||
token.attrs = attrs; | ||
token.content = content; | ||
token.start = start; | ||
token.end = streamer.clone_cursor_position(); | ||
} | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
19785
2
565