Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

htmltemplate-transform

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

htmltemplate-transform - npm Package Compare versions

Comparing version 1.0.11 to 2.0.0

7

package.json
{
"name": "htmltemplate-transform",
"version": "1.0.11",
"version": "2.0.0",
"description": "Pluggable transforms for HTML::Template",
"main": "index.js",
"scripts": {
"test": "mocha 'test/**/*.js' --bail"
"test": "mocha test/**/*.js --bail"
},

@@ -19,3 +19,4 @@ "keywords": [

"dependencies": {
"htmltemplate-parser": "0.4.4",
"find-index": "1.1.0",
"htmltemplate-parser": "1.0.2",
"object-assign": "4.0.1",

@@ -22,0 +23,0 @@ "traverse": "0.6.6",

@@ -16,3 +16,3 @@ var fs = require('fs');

var blocks = {};
var blocks = [];

@@ -24,12 +24,18 @@ function transform(node, isNested) {

var state = this.state;
// On each include call a TMPL_BLOCK definition is created in the top
// level scope which is then TMPL_INLINEd into the original location.
// Block paths are hashed to avoid duplication.
// Block paths are namespaced to avoid duplication.
if (this.isRoot && !isNested) {
this.state.parentFilePath = this.state.rootFilepath;
state.parentFilePath = state.rootFilepath;
this.after(function(root) {
var uniqueBlocks = deduplicate(blocks, function(block) {
return block.id;
});
this.update(
Object.keys(blocks)
.map(function(id) {
uniqueBlocks
.map(function(block) {
return {

@@ -41,6 +47,6 @@ type: 'Tag',

type: 'SingleAttribute',
name: id
name: block.id
}
],
content: blocks[id]
content: block.content
};

@@ -51,18 +57,35 @@ })

blocks = {};
blocks = [];
});
}
if (tags.indexOf(node.name) !== -1) {
var state = this.state;
if (isBlockTag(node)) {
var blockName = getPrimaryAttributeValue(node.attributes);
var filename = getPrimaryAttributeValue(node.attributes);
var extname = path.extname(filename);
var id = filepathAsBlockId(
getLocalBlockIdentifier(blockName, state.parentFilePath, state.rootFilepath)
);
if (extname !== '.inc' && extname !== '.tmpl') {
return;
}
blocks.push({
id: id,
content: node.content
});
var include = resolvePath(node.name, state.parentFilePath, filename);
this.update({
type: 'Text',
content: '',
position: node.position
});
}
if (tags.indexOf(node.name) !== -1) {
var blockName = getPrimaryAttributeValue(node.attributes);
var filepath = resolvePath(node.name, state.parentFilePath, blockName);
var extname = path.extname(filepath);
var isFileInclude = (
extname === '.inc' ||
extname === '.tmpl'
);
var id = filepathAsBlockId(

@@ -72,20 +95,16 @@ // Resolving the included filepath against root filepath to

// location.
path.relative(path.dirname(state.rootFilepath), include)
isFileInclude ?
path.relative(path.dirname(state.rootFilepath), filepath) :
// Local TMPL_BLOCK calls are namespaced and renamed to
// `%blockname.local` for a safer deduplication.
getLocalBlockIdentifier(blockName, state.parentFilePath, state.rootFilepath)
);
var ast = parser.parse(
fs.readFileSync(include, 'utf8'),
state.parserOptions
);
var updated = traverse(ast).map(function(n) {
this.state = assign({}, state, {
parentFilePath: include
if (isFileInclude) {
blocks.push({
id: id,
content: getFileBlockContent(filepath, state, transform)
});
}
transform.call(this, n, true);
});
blocks[id] = updated;
var attributes = node.attributes.map(function(attribute) {

@@ -111,4 +130,48 @@ if (isPrimaryAttribute(attribute)) {

return transform;
function getFileBlockContent(filepath, state, transform) {
var ast = parser.parse(
fs.readFileSync(filepath, 'utf8'),
state.parserOptions
);
return traverse(ast).map(function(n) {
this.state = assign({}, state, {
parentFilePath: filepath
});
transform.call(this, n, true);
});
}
}
function getLocalBlockIdentifier(name, parentFilePath, rootFilepath) {
return path.join(
path.relative(path.dirname(rootFilepath), parentFilePath),
name + '.local'
);
}
function deduplicate(array, predicate) {
var seen = {};
return array.filter(function(item, index) {
var value = predicate(item, index);
if (value in seen) {
return false;
} else {
seen[value] = true;
return true;
}
});
}
function isBlockTag(node) {
return (
node.type === 'Tag' &&
node.name === 'TMPL_BLOCK'
);
}
function isPrimaryAttribute(attribute) {

@@ -115,0 +178,0 @@ return (

@@ -21,13 +21,11 @@ var assign = require('object-assign');

if (node.type === 'PairAttribute' && isJPathAccessToken(node.content)) {
if (node.type === 'PairAttribute' && isJPathAccessToken(node.value)) {
var updated = assign({}, node, {
value: {
type: 'Expression',
content: accessExpression(node.value),
value: node.value
content: accessExpression(node.value.name),
value: node.value.name
}
});
delete updated.content;
this.update(updated);

@@ -34,0 +32,0 @@ }

@@ -103,3 +103,3 @@ var NOT_SURE = {};

// very basic implementation for now
if (node.name === 'TMPL_SETVAR') {
if (node.type === 'Tag' && node.name === 'TMPL_SETVAR') {
var identifierName = String(node.attributes[0].name);

@@ -106,0 +106,0 @@

var assert = require('assert');
var assign = require('object-assign');
var findIndex = require('find-index');

@@ -129,12 +130,2 @@ module.exports = function(options) {

function findIndex(list, predicate) {
for (var i = 0, len = list.length; i < len; i += 1) {
if (predicate(list[i])) {
return i;
}
}
return -1;
}
function idGenerator(prefix) {

@@ -141,0 +132,0 @@ var counter = 0;

@@ -0,1 +1,4 @@

var assign = require('object-assign');
var findIndex = require('find-index');
var TRUE_LITERAL = {

@@ -17,34 +20,43 @@ type: 'Literal',

if (node.type === 'ConditionalAttribute') {
var transformedAttributes = {};
var conditions = node.conditions.slice();
if (hasConditionalAttributes(node)) {
var updatedAttributes = [];
if (node.otherwise) {
conditions.push({
type: 'ConditionBranch',
content: node.otherwise
});
}
node.forEach(function(attribute) {
if (!isConditionalAttribute(attribute)) {
updatedAttributes.push(attribute);
conditions.forEach(function(c, index) {
c.content.forEach(function(attr) {
var attributeName = attr.name;
var attributeContent = getConsequentAttributeContent(attr);
return;
}
var precondition = getPrecondition(
conditions.slice(0, index),
c.condition
);
var conditions = attribute.conditions.slice();
var expressionContent = {
type: 'ConditionalExpression',
test: precondition,
consequent: attributeContent,
alternate: NULL_LITERAL
};
if (attribute.otherwise) {
conditions.push({
type: 'ConditionBranch',
content: attribute.otherwise
});
}
if (transformedAttributes[attributeName]) {
transformedAttributes[attributeName].value.content.alternate = expressionContent;
} else {
transformedAttributes[attributeName] = {
conditions.forEach(function(c, index) {
c.content.forEach(function(attr) {
var attributeName = attr.name;
var attributeContent = getConsequentAttributeContent(attr);
var precondition = getPrecondition(
conditions.slice(0, index),
c.condition
);
var expressionContent = {
type: 'ConditionalExpression',
test: precondition,
consequent: attributeContent,
alternate: NULL_LITERAL
};
var existingAttributeIndex = findIndex(updatedAttributes, function(attribute) {
return attribute.name === attributeName;
});
var transformedConditionalAttribute = {
type: 'PairAttribute',

@@ -57,24 +69,17 @@ name: attributeName,

};
}
});
});
this.parent.post(function() {
var parentNode = this.node;
this.update(
parentNode.reduce(function(updatedAttributes, attribute) {
if (attribute === node) {
for (var attributeName in transformedAttributes) {
updatedAttributes.push(transformedAttributes[attributeName]);
if (existingAttributeIndex === -1) {
updatedAttributes.push(transformedConditionalAttribute);
} else {
if (isTransformedConditionalAttribute(updatedAttributes[existingAttributeIndex])) {
updatedAttributes[existingAttributeIndex].value.content.alternate = expressionContent;
} else {
updatedAttributes[existingAttributeIndex] = transformedConditionalAttribute;
}
} else {
updatedAttributes.push(attribute);
}
});
});
});
return updatedAttributes;
}, []),
true
);
});
this.update(updatedAttributes, true);
}

@@ -147,1 +152,20 @@ };

}
function isConditionalAttribute(node) {
return node.type === 'ConditionalAttribute';
}
function hasConditionalAttributes(node) {
return (
Array.isArray(node) &&
node.some(isConditionalAttribute)
);
}
function isTransformedConditionalAttribute(attribute) {
return (
attribute.type === 'PairAttribute' &&
attribute.value.type === 'Expression' &&
attribute.value.content.type === 'ConditionalExpression'
);
}
var assert = require('assert');
var assign = require('object-assign');
var findLastIndex = require('find-index/findLastIndex');

@@ -25,3 +26,3 @@ var NON_WHITESPACE = /\S/;

var closestLoopIndex = lastIndexOf(parents, function(parent) {
var closestLoopIndex = findLastIndex(parents, function(parent) {
return isLoop(parent.node);

@@ -34,3 +35,3 @@ });

var closestContentNodeIndex = lastIndexOf(this.path, function(segment, index, path) {
var closestContentNodeIndex = findLastIndex(this.path, function(segment, index, path) {
return (

@@ -238,12 +239,2 @@ (index >= 2 && path[index - 2] === 'otherwise') ||

function lastIndexOf(list, fn) {
for (var i = (list.length - 1); i >= 0; i -= 1) {
if (fn(list[i], i, list)) {
return i;
}
}
return -1;
}
function pathKey(path) {

@@ -250,0 +241,0 @@ return path.join('.');

@@ -8,3 +8,3 @@ [

"type": "SingleAttribute",
"name": "inc_nested_include_inc"
"name": "inc_include_inc_decorated_title_local"
}

@@ -14,4 +14,12 @@ ],

{
"type": "Text",
"content": "\n ",
"position": {
"line": 1,
"column": 29
}
},
{
"type": "HTMLTag",
"name": "h2",
"name": "b",
"attributes": [],

@@ -28,4 +36,4 @@ "content": [

"position": {
"line": 1,
"column": 15
"line": 2,
"column": 18
}

@@ -35,4 +43,4 @@ }

"position": {
"line": 1,
"column": 5
"line": 2,
"column": 8
}

@@ -42,13 +50,144 @@ }

"position": {
"line": 2,
"column": 5
}
},
{
"type": "Text",
"content": "\n",
"position": {
"line": 2,
"column": 28
}
}
]
},
{
"type": "Tag",
"name": "TMPL_BLOCK",
"attributes": [
{
"type": "SingleAttribute",
"name": "inc_nested_include_inc_decorated_title_local"
}
],
"content": [
{
"type": "Text",
"content": "\n ",
"position": {
"line": 1,
"column": 1
"column": 29
}
},
{
"type": "HTMLTag",
"name": "u",
"attributes": [],
"content": [
{
"type": "Tag",
"name": "TMPL_VAR",
"attributes": [
{
"type": "SingleAttribute",
"name": "title",
"value": null,
"position": {
"line": 2,
"column": 18
}
}
],
"position": {
"line": 2,
"column": 8
}
}
],
"position": {
"line": 2,
"column": 5
}
},
{
"type": "Text",
"content": "\n",
"position": {
"line": 2,
"column": 28
}
}
]
},
{
"type": "Tag",
"name": "TMPL_BLOCK",
"attributes": [
{
"type": "SingleAttribute",
"name": "inc_nested_include_inc"
}
],
"content": [
{
"type": "Text",
"content": "",
"position": {
"line": 1,
"column": 26
"column": 1
}
},
{
"type": "Text",
"content": "\n\n",
"position": {
"line": 3,
"column": 14
}
},
{
"type": "HTMLTag",
"name": "h2",
"attributes": [],
"content": [
{
"type": "Tag",
"name": "TMPL_INLINE",
"attributes": [
{
"type": "SingleAttribute",
"name": "inc_nested_include_inc_decorated_title_local"
},
{
"type": "PairAttribute",
"name": "title",
"value": {
"type": "Identifier",
"name": "title",
"position": {
"line": 5,
"column": 40
}
},
"position": {
"line": 5,
"column": 34
}
}
]
}
],
"position": {
"line": 5,
"column": 1
}
},
{
"type": "Text",
"content": "\n",
"position": {
"line": 5,
"column": 51
}
}

@@ -68,2 +207,18 @@ ]

{
"type": "Text",
"content": "",
"position": {
"line": 1,
"column": 1
}
},
{
"type": "Text",
"content": "\n\n",
"position": {
"line": 3,
"column": 14
}
},
{
"type": "HTMLTag",

@@ -75,5 +230,5 @@ "name": "h1",

"type": "Text",
"content": "\n Included\n ",
"content": "\n ",
"position": {
"line": 1,
"line": 5,
"column": 5

@@ -88,2 +243,45 @@ }

"type": "SingleAttribute",
"name": "inc_include_inc_decorated_title_local"
},
{
"type": "PairAttribute",
"name": "title",
"value": {
"type": "Expression",
"content": {
"type": "Literal",
"value": "Included",
"raw": "'Included'",
"position": {
"line": 7,
"column": 18
}
},
"value": "'Included'",
"position": {
"line": 7,
"column": 15
}
},
"position": {
"line": 7,
"column": 9
}
}
]
},
{
"type": "Text",
"content": "\n ",
"position": {
"line": 7,
"column": 32
}
},
{
"type": "Tag",
"name": "TMPL_INLINE",
"attributes": [
{
"type": "SingleAttribute",
"name": "inc_nested_include_inc"

@@ -94,8 +292,8 @@ },

"name": "title",
"value": "Nested",
"content": {
"value": {
"type": "Literal",
"value": "Nested",
"raw": "\"Nested\"",
"position": {
"line": 4,
"line": 9,
"column": 15

@@ -105,3 +303,3 @@ }

"position": {
"line": 4,
"line": 9,
"column": 9

@@ -116,3 +314,3 @@ }

"position": {
"line": 4,
"line": 9,
"column": 24

@@ -123,3 +321,3 @@ }

"position": {
"line": 1,
"line": 5,
"column": 1

@@ -132,3 +330,3 @@ }

"position": {
"line": 5,
"line": 10,
"column": 6

@@ -191,6 +389,6 @@ }

"name": "title",
"value": "Top level",
"content": {
"value": {
"type": "Literal",
"value": "Top level",
"raw": "\"Top level\"",
"position": {

@@ -230,2 +428,2 @@ "line": 4,

}
]
]

@@ -23,3 +23,3 @@ var fs = require('fs');

include({
includeTags: ['TMPL_INCLUDE'],
includeTags: ['TMPL_INCLUDE', 'TMPL_INLINE'],
resolvePath: function(tagname, from, to) {

@@ -26,0 +26,0 @@ return path.resolve(path.dirname(from), to);

@@ -297,6 +297,6 @@ [

"name": "attribute",
"value": "dotted.string",
"content": {
"value": {
"type": "Literal",
"value": "dotted.string",
"raw": "\"dotted.string\"",
"position": {

@@ -377,2 +377,2 @@ "line": 6,

}
]
]

@@ -168,2 +168,3 @@ [

"value": 0,
"raw": 0,
"position": {

@@ -471,2 +472,3 @@ "line": 16,

"value": 1,
"raw": 1,
"position": {

@@ -678,2 +680,6 @@ "line": 30,

"column": 5
},
"stringEntities": {
"before": "<",
"after": ">"
}

@@ -706,2 +712,6 @@ },

"column": 5
},
"stringEntities": {
"before": "<",
"after": ">"
}

@@ -753,2 +763,29 @@ },

"column": 1
},
"stringEntities": {
"start": {
"name": "TMPL_SETVAR",
"attributes": [
{
"type": "SingleAttribute",
"name": "setvar_falsy",
"value": null,
"position": {
"line": 44,
"column": 14
}
}
],
"stringEntities": {
"before": "<",
"after": ">"
}
},
"end": {
"name": "TMPL_SETVAR",
"stringEntities": {
"before": "</",
"after": ">"
}
}
}

@@ -791,2 +828,29 @@ },

"column": 1
},
"stringEntities": {
"start": {
"name": "TMPL_SETVAR",
"attributes": [
{
"type": "SingleAttribute",
"name": "setvar_truthy",
"value": null,
"position": {
"line": 45,
"column": 14
}
}
],
"stringEntities": {
"before": "<",
"after": ">"
}
},
"end": {
"name": "TMPL_SETVAR",
"stringEntities": {
"before": "</",
"after": ">"
}
}
}

@@ -856,2 +920,3 @@ },

"value": 0,
"raw": 0,
"position": {

@@ -876,2 +941,6 @@ "line": 52,

"column": 1
},
"stringEntities": {
"before": "<",
"after": ">"
}

@@ -905,2 +974,3 @@ },

"value": 1,
"raw": 1,
"position": {

@@ -925,2 +995,6 @@ "line": 53,

"column": 1
},
"stringEntities": {
"before": "<",
"after": ">"
}

@@ -973,2 +1047,6 @@ },

"column": 1
},
"stringEntities": {
"before": "<",
"after": ">"
}

@@ -975,0 +1053,0 @@ },

@@ -153,2 +153,3 @@ [

"value": 4,
"raw": 4,
"position": {

@@ -383,2 +384,3 @@ "line": 6,

"value": 10,
"raw": 10,
"position": {

@@ -385,0 +387,0 @@ "line": 15,

@@ -207,2 +207,3 @@ [

"value": "submit",
"raw": "'submit'",
"position": {

@@ -228,2 +229,3 @@ "line": 6,

"value": "tel",
"raw": "'tel'",
"position": {

@@ -282,2 +284,3 @@ "line": 6,

"value": "submit",
"raw": "'submit'",
"position": {

@@ -303,2 +306,3 @@ "line": 6,

"value": "tel",
"raw": "'tel'",
"position": {

@@ -327,2 +331,3 @@ "line": 6,

"value": "tel",
"raw": "'tel'",
"position": {

@@ -524,3 +529,3 @@ "line": 8,

"type": "Text",
"content": "\n",
"content": "\n ",
"position": {

@@ -530,2 +535,351 @@ "line": 23,

}
},
{
"type": "HTMLTag",
"name": "button",
"attributes": [
{
"type": "PairAttribute",
"name": "data-key",
"value": {
"type": "Expression",
"content": {
"type": "ConditionalExpression",
"test": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "$button",
"position": {
"line": 25,
"column": 21
}
},
"property": {
"type": "Literal",
"value": "available",
"position": {
"line": 25,
"column": 28
}
},
"computed": true
},
"consequent": [
{
"type": "Tag",
"name": "TMPL_VAR",
"attributes": [
{
"type": "Expression",
"content": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "$button",
"position": {
"line": 25,
"column": 68
}
},
"property": {
"type": "Literal",
"value": "key",
"position": {
"line": 25,
"column": 75
}
},
"computed": true
},
"value": "$button->{key}",
"position": {
"line": 25,
"column": 65
}
}
],
"position": {
"line": 25,
"column": 55
}
}
],
"alternate": {
"type": "Literal",
"value": null
}
}
}
},
{
"type": "PairAttribute",
"name": "disabled",
"value": {
"type": "Expression",
"content": {
"type": "ConditionalExpression",
"test": {
"type": "UnaryExpression",
"operator": "!",
"argument": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "$button",
"position": {
"line": 25,
"column": 21
}
},
"property": {
"type": "Literal",
"value": "available",
"position": {
"line": 25,
"column": 28
}
},
"computed": true
},
"prefix": true
},
"consequent": [
{
"type": "Literal",
"value": "true"
}
],
"alternate": {
"type": "ConditionalExpression",
"test": {
"type": "BinaryExpression",
"operator": "&&",
"left": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "$button",
"position": {
"line": 26,
"column": 21
}
},
"property": {
"type": "Literal",
"value": "available",
"position": {
"line": 26,
"column": 28
}
},
"computed": true
},
"right": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "$button",
"position": {
"line": 26,
"column": 45
}
},
"property": {
"type": "Literal",
"value": "type",
"position": {
"line": 26,
"column": 52
}
},
"computed": true
}
},
"consequent": [
{
"type": "Literal",
"value": true
}
],
"alternate": {
"type": "Literal",
"value": null
}
}
}
}
},
{
"type": "PairAttribute",
"name": "class",
"value": {
"type": "Expression",
"content": {
"type": "ConditionalExpression",
"test": {
"type": "BinaryExpression",
"operator": "&&",
"left": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "$button",
"position": {
"line": 26,
"column": 21
}
},
"property": {
"type": "Literal",
"value": "available",
"position": {
"line": 26,
"column": 28
}
},
"computed": true
},
"right": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "$button",
"position": {
"line": 26,
"column": 45
}
},
"property": {
"type": "Literal",
"value": "type",
"position": {
"line": 26,
"column": 52
}
},
"computed": true
}
},
"consequent": [
{
"type": "Text",
"content": "button-",
"position": {
"line": 26,
"column": 71
}
},
{
"type": "Tag",
"name": "TMPL_VAR",
"attributes": [
{
"type": "Expression",
"content": {
"type": "MemberExpression",
"object": {
"type": "Identifier",
"name": "$button",
"position": {
"line": 26,
"column": 91
}
},
"property": {
"type": "Literal",
"value": "type",
"position": {
"line": 26,
"column": 98
}
},
"computed": true
},
"value": "$button->{type}",
"position": {
"line": 26,
"column": 88
}
}
],
"position": {
"line": 26,
"column": 78
}
}
],
"alternate": {
"type": "Literal",
"value": null
}
}
}
}
],
"content": [
{
"type": "Text",
"content": "\n OK\n ",
"position": {
"line": 26,
"column": 131
}
}
],
"position": {
"line": 24,
"column": 5
}
},
{
"type": "Text",
"content": "\n ",
"position": {
"line": 28,
"column": 14
}
},
{
"type": "HTMLTag",
"name": "div",
"attributes": [
{
"type": "PairAttribute",
"name": "class",
"value": {
"type": "Expression",
"content": {
"type": "ConditionalExpression",
"test": {
"type": "Identifier",
"name": "$use_inline"
},
"consequent": [
{
"type": "Literal",
"value": "inline"
}
],
"alternate": {
"type": "Literal",
"value": null
}
}
}
}
],
"content": [],
"position": {
"line": 29,
"column": 5
}
},
{
"type": "Text",
"content": "\n",
"position": {
"line": 29,
"column": 75
}
}

@@ -542,6 +896,6 @@ ],

"position": {
"line": 24,
"line": 30,
"column": 7
}
}
]
]

@@ -18,4 +18,3 @@ [

"name": "IN",
"value": "b_list",
"content": {
"value": {
"type": "Identifier",

@@ -22,0 +21,0 @@ "name": "b_list",

@@ -18,4 +18,3 @@ [

"name": "IN",
"value": "b_list",
"content": {
"value": {
"type": "Identifier",

@@ -22,0 +21,0 @@ "name": "b_list",

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc