Skip to content

Commit 9f660c7

Browse files
Split in multiple files
1 parent 9f4216f commit 9f660c7

8 files changed

+484
-439
lines changed

src/attributes.js

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
'use strict';
2+
3+
const parseAttrs = require('posthtml-attrs-parser');
4+
const styleToObject = require('style-to-object');
5+
6+
/**
7+
* Map component attributes that it's not defined as locals to first element of node
8+
*
9+
* @param {Object} currentNode
10+
* @param {Object} attributes
11+
* @param {Object} locals
12+
* @param {Object} options
13+
* @return {void}
14+
*/
15+
module.exports = (currentNode, attributes, locals, options) => {
16+
// Find by attribute 'attributes' ??
17+
const index = currentNode.content.findIndex(content => typeof content === 'object');
18+
19+
if (index === -1) {
20+
return;
21+
}
22+
23+
const nodeAttrs = parseAttrs(currentNode.content[index].attrs, options.attrsParserRules);
24+
25+
Object.keys(attributes).forEach(attr => {
26+
if (typeof locals[attr] === 'undefined' && !Object.keys(options.aware).includes(attr)) {
27+
if (['class'].includes(attr)) {
28+
if (typeof nodeAttrs.class === 'undefined') {
29+
nodeAttrs.class = [];
30+
}
31+
32+
nodeAttrs.class.push(attributes.class);
33+
delete attributes.class;
34+
} else if (['override:class'].includes(attr)) {
35+
nodeAttrs.class = attributes['override:class'];
36+
delete attributes['override:class'];
37+
} else if (['style'].includes(attr)) {
38+
if (typeof nodeAttrs.style === 'undefined') {
39+
nodeAttrs.style = {};
40+
}
41+
42+
nodeAttrs.style = Object.assign(nodeAttrs.style, styleToObject(attributes.style));
43+
delete attributes.style;
44+
} else if (['override:style'].includes(attr)) {
45+
nodeAttrs.style = attributes['override:style'];
46+
delete attributes['override:style'];
47+
} else if (!attr.startsWith('$') && attr !== options.attribute) {
48+
nodeAttrs[attr] = attributes[attr];
49+
delete attributes[attr];
50+
}
51+
}
52+
});
53+
54+
currentNode.content[index].attrs = nodeAttrs.compose();
55+
};

src/find-path-in-namespaces.js

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
'use strict';
2+
3+
const path = require('path');
4+
const {existsSync} = require('fs');
5+
const findPathInRoots = require('./find-path-in-roots');
6+
7+
/**
8+
* Find component file within all defined namespaces path
9+
*
10+
* @param {String} tag [tag name with namespace]
11+
* @param {String} namespace [tag's namespace]
12+
* @param {String} fileNameFromTag [filename converted from tag name]
13+
* @param {Object} options [posthtml options]
14+
* @return {String|boolean} [custom tag root where the module is found]
15+
*/
16+
function findPathInNamespaces(tag, [namespace, fileNameFromTag], options) {
17+
const customTagNamespace = options.namespaces.find(n => n.name === namespace.replace(options.tagPrefix, ''));
18+
19+
if (!customTagNamespace) {
20+
if (options.strict) {
21+
throw new Error(`[components] Unknown module namespace ${namespace}.`);
22+
} else {
23+
return false;
24+
}
25+
}
26+
27+
// Used to check module by index.html
28+
const indexFileNameFromTag = fileNameFromTag
29+
.replace(`.${options.fileExtension}`, '')
30+
.concat(path.sep, 'index.', options.fileExtension);
31+
32+
// First check in defined namespace's custom root if module was overridden
33+
let foundByIndexFile = false;
34+
if (customTagNamespace.custom && (existsSync(path.join(customTagNamespace.custom, fileNameFromTag)) || (foundByIndexFile = existsSync(path.join(customTagNamespace.custom, indexFileNameFromTag))))) {
35+
customTagNamespace.root = customTagNamespace.custom;
36+
if (foundByIndexFile) {
37+
fileNameFromTag = indexFileNameFromTag;
38+
}
39+
// Then check in defined namespace's or fallback path
40+
} else if (!existsSync(path.join(customTagNamespace.root, fileNameFromTag))) {
41+
if (existsSync(path.join(customTagNamespace.root, indexFileNameFromTag))) {
42+
// Module found in folder `tag-name/index.html`
43+
fileNameFromTag = indexFileNameFromTag;
44+
} else if (customTagNamespace.fallback && (existsSync(path.join(customTagNamespace.fallback, fileNameFromTag)) || (foundByIndexFile = existsSync(path.join(customTagNamespace.fallback, indexFileNameFromTag))))) {
45+
// Module found in defined namespace fallback
46+
customTagNamespace.root = customTagNamespace.fallback;
47+
if (foundByIndexFile) {
48+
fileNameFromTag = indexFileNameFromTag;
49+
}
50+
} else if (options.namespaceFallback) {
51+
// Last resort: try to find module by defined roots as fallback
52+
try {
53+
// Passing tag name without namespace, although it's only used
54+
// for error message which in this case it's not even used.
55+
// But passing it correctly in case in future we do something
56+
// with tag name inside findModuleByRoot()
57+
return findPathInRoots(tag.replace(namespace, '').replace(options.namespaceSeparator, ''), fileNameFromTag, options);
58+
} catch {
59+
// With disabled strict mode we will never enter here as findPathByRoot() return false
60+
// so we don't need to check if options.strict is true
61+
throw new Error(`[components] For the tag ${tag} was not found the template in the defined namespace's root ${customTagNamespace.root} nor in any defined custom tag roots.`);
62+
}
63+
} else if (options.strict) {
64+
throw new Error(`[components] For the tag ${tag} was not found the template in the defined namespace's path ${customTagNamespace.root}.`);
65+
} else {
66+
return false;
67+
}
68+
}
69+
70+
// Set root to namespace root
71+
options.root = customTagNamespace.root;
72+
return fileNameFromTag;
73+
}
74+
75+
module.exports = (tag, [namespace, fileNameFromTag], options) => findPathInNamespaces(tag, [namespace, fileNameFromTag], options);

src/find-path-in-roots.js

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
'use strict';
2+
3+
const path = require('path');
4+
const {existsSync} = require('fs');
5+
6+
/**
7+
* Find component file within all defined roots path
8+
*
9+
* @param {String} tag [tag name]
10+
* @param {String} fileNameFromTag [filename converted from tag name]
11+
* @param {Object} options [posthtml options]
12+
* @return {String|boolean} [custom tag root where the module is found]
13+
*/
14+
function findPathInRoots(tag, fileNameFromTag, options) {
15+
let root = options.roots.find(root => existsSync(path.join(root, fileNameFromTag)));
16+
17+
if (!root) {
18+
// Check if module exist in folder `tag-name/index.html`
19+
fileNameFromTag = fileNameFromTag
20+
.replace(`.${options.fileExtension}`, '')
21+
.concat(path.sep, 'index.', options.fileExtension);
22+
23+
root = options.roots.find(root => existsSync(path.join(root, fileNameFromTag)));
24+
}
25+
26+
if (!root) {
27+
if (options.strict) {
28+
throw new Error(`[components] For the tag ${tag} was not found the template in any defined root path ${options.roots.join(', ')}`);
29+
} else {
30+
return false;
31+
}
32+
}
33+
34+
return path.join(root, fileNameFromTag);
35+
}
36+
37+
module.exports = (tag, fileNameFromTag, options) => findPathInRoots(tag, fileNameFromTag, options);

src/find-path.js

+6-106
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
'use strict';
22

33
const path = require('path');
4-
const {existsSync} = require('fs');
4+
const findPathInRoots = require('./find-path-in-roots');
5+
const findPathInNamespaces = require('./find-path-in-namespaces');
56

67
const folderSeparator = '.';
78

@@ -12,7 +13,7 @@ const folderSeparator = '.';
1213
* @param {Object} options [posthtml options]
1314
* @return {String|boolean}
1415
*/
15-
function findPathFromTagName({tag}, options) {
16+
module.exports = ({tag}, options) => {
1617
// Get module filename from tag name
1718
// remove prefix "x-"
1819
// replace dot "." with slash "/"
@@ -26,107 +27,6 @@ function findPathFromTagName({tag}, options) {
2627
// Find module by defined namespace in options.namespaces when tag has '::'
2728
// otherwise by defined roots in options.roots
2829
return tag.includes(options.namespaceSeparator) ?
29-
findPathByNamespace(tag, fileNameFromTag.split(options.namespaceSeparator), options) :
30-
findPathByRoot(tag, fileNameFromTag, options);
31-
}
32-
33-
/**
34-
* Search for module file within namespace path
35-
*
36-
* @param {String} tag [tag name with namespace]
37-
* @param {String} namespace [tag's namespace]
38-
* @param {String} fileNameFromTag [filename converted from tag name]
39-
* @param {Object} options [posthtml options]
40-
* @return {String|boolean} [custom tag root where the module is found]
41-
*/
42-
function findPathByNamespace(tag, [namespace, fileNameFromTag], options) {
43-
const customTagNamespace = options.namespaces.find(n => n.name === namespace.replace(options.tagPrefix, ''));
44-
45-
if (!customTagNamespace) {
46-
if (options.strict) {
47-
throw new Error(`[components] Unknown module namespace ${namespace}.`);
48-
} else {
49-
return false;
50-
}
51-
}
52-
53-
// Used to check module by index.html
54-
const indexFileNameFromTag = fileNameFromTag
55-
.replace(`.${options.fileExtension}`, '')
56-
.concat(path.sep, 'index.', options.fileExtension);
57-
58-
// First check in defined namespace's custom root if module was overridden
59-
let foundByIndexFile = false;
60-
if (customTagNamespace.custom && (existsSync(path.join(customTagNamespace.custom, fileNameFromTag)) || (foundByIndexFile = existsSync(path.join(customTagNamespace.custom, indexFileNameFromTag))))) {
61-
customTagNamespace.root = customTagNamespace.custom;
62-
if (foundByIndexFile) {
63-
fileNameFromTag = indexFileNameFromTag;
64-
}
65-
// Then check in defined namespace's or fallback path
66-
} else if (!existsSync(path.join(customTagNamespace.root, fileNameFromTag))) {
67-
if (existsSync(path.join(customTagNamespace.root, indexFileNameFromTag))) {
68-
// Module found in folder `tag-name/index.html`
69-
fileNameFromTag = indexFileNameFromTag;
70-
} else if (customTagNamespace.fallback && (existsSync(path.join(customTagNamespace.fallback, fileNameFromTag)) || (foundByIndexFile = existsSync(path.join(customTagNamespace.fallback, indexFileNameFromTag))))) {
71-
// Module found in defined namespace fallback
72-
customTagNamespace.root = customTagNamespace.fallback;
73-
if (foundByIndexFile) {
74-
fileNameFromTag = indexFileNameFromTag;
75-
}
76-
} else if (options.namespaceFallback) {
77-
// Last resort: try to find module by defined roots as fallback
78-
try {
79-
// Passing tag name without namespace, although it's only used
80-
// for error message which in this case it's not even used.
81-
// But passing it correctly in case in future we do something
82-
// with tag name inside findModuleByRoot()
83-
return findPathByRoot(tag.replace(namespace, '').replace(options.namespaceSeparator, ''), fileNameFromTag, options);
84-
} catch {
85-
// With disabled strict mode we will never enter here as findPathByRoot() return false
86-
// so we don't need to check if options.strict is true
87-
throw new Error(`[components] For the tag ${tag} was not found the template in the defined namespace's root ${customTagNamespace.root} nor in any defined custom tag roots.`);
88-
}
89-
} else if (options.strict) {
90-
throw new Error(`[components] For the tag ${tag} was not found the template in the defined namespace's path ${customTagNamespace.root}.`);
91-
} else {
92-
return false;
93-
}
94-
}
95-
96-
// Set root to namespace root
97-
options.root = customTagNamespace.root;
98-
return fileNameFromTag;
99-
}
100-
101-
/**
102-
* Search for module file within all roots
103-
*
104-
* @param {String} tag [tag name]
105-
* @param {String} fileNameFromTag [filename converted from tag name]
106-
* @param {Object} options [posthtml options]
107-
* @return {String|boolean} [custom tag root where the module is found]
108-
*/
109-
function findPathByRoot(tag, fileNameFromTag, options) {
110-
let root = options.roots.find(root => existsSync(path.join(root, fileNameFromTag)));
111-
112-
if (!root) {
113-
// Check if module exist in folder `tag-name/index.html`
114-
fileNameFromTag = fileNameFromTag
115-
.replace(`.${options.fileExtension}`, '')
116-
.concat(path.sep, 'index.', options.fileExtension);
117-
118-
root = options.roots.find(root => existsSync(path.join(root, fileNameFromTag)));
119-
}
120-
121-
if (!root) {
122-
if (options.strict) {
123-
throw new Error(`[components] For the tag ${tag} was not found the template in any defined root path ${options.roots.join(', ')}`);
124-
} else {
125-
return false;
126-
}
127-
}
128-
129-
return path.join(root, fileNameFromTag);
130-
}
131-
132-
module.exports = (node, options) => findPathFromTagName(node, options);
30+
findPathInNamespaces(tag, fileNameFromTag.split(options.namespaceSeparator), options) :
31+
findPathInRoots(tag, fileNameFromTag, options);
32+
};

0 commit comments

Comments
 (0)