Skip to content

Commit

Permalink
Split in multiple files
Browse files Browse the repository at this point in the history
  • Loading branch information
thewebartisan7 committed Oct 18, 2022
1 parent 9f4216f commit 9f660c7
Show file tree
Hide file tree
Showing 8 changed files with 484 additions and 439 deletions.
55 changes: 55 additions & 0 deletions src/attributes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
'use strict';

const parseAttrs = require('posthtml-attrs-parser');
const styleToObject = require('style-to-object');

/**
* Map component attributes that it's not defined as locals to first element of node
*
* @param {Object} currentNode
* @param {Object} attributes
* @param {Object} locals
* @param {Object} options
* @return {void}
*/
module.exports = (currentNode, attributes, locals, options) => {
// Find by attribute 'attributes' ??
const index = currentNode.content.findIndex(content => typeof content === 'object');

if (index === -1) {
return;
}

const nodeAttrs = parseAttrs(currentNode.content[index].attrs, options.attrsParserRules);

Object.keys(attributes).forEach(attr => {
if (typeof locals[attr] === 'undefined' && !Object.keys(options.aware).includes(attr)) {
if (['class'].includes(attr)) {
if (typeof nodeAttrs.class === 'undefined') {
nodeAttrs.class = [];
}

nodeAttrs.class.push(attributes.class);
delete attributes.class;
} else if (['override:class'].includes(attr)) {
nodeAttrs.class = attributes['override:class'];
delete attributes['override:class'];
} else if (['style'].includes(attr)) {
if (typeof nodeAttrs.style === 'undefined') {
nodeAttrs.style = {};
}

nodeAttrs.style = Object.assign(nodeAttrs.style, styleToObject(attributes.style));
delete attributes.style;
} else if (['override:style'].includes(attr)) {
nodeAttrs.style = attributes['override:style'];
delete attributes['override:style'];
} else if (!attr.startsWith('$') && attr !== options.attribute) {
nodeAttrs[attr] = attributes[attr];
delete attributes[attr];
}
}
});

currentNode.content[index].attrs = nodeAttrs.compose();
};
75 changes: 75 additions & 0 deletions src/find-path-in-namespaces.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
'use strict';

const path = require('path');
const {existsSync} = require('fs');
const findPathInRoots = require('./find-path-in-roots');

/**
* Find component file within all defined namespaces path
*
* @param {String} tag [tag name with namespace]
* @param {String} namespace [tag's namespace]
* @param {String} fileNameFromTag [filename converted from tag name]
* @param {Object} options [posthtml options]
* @return {String|boolean} [custom tag root where the module is found]
*/
function findPathInNamespaces(tag, [namespace, fileNameFromTag], options) {
const customTagNamespace = options.namespaces.find(n => n.name === namespace.replace(options.tagPrefix, ''));

if (!customTagNamespace) {
if (options.strict) {
throw new Error(`[components] Unknown module namespace ${namespace}.`);
} else {
return false;
}
}

// Used to check module by index.html
const indexFileNameFromTag = fileNameFromTag
.replace(`.${options.fileExtension}`, '')
.concat(path.sep, 'index.', options.fileExtension);

// First check in defined namespace's custom root if module was overridden
let foundByIndexFile = false;
if (customTagNamespace.custom && (existsSync(path.join(customTagNamespace.custom, fileNameFromTag)) || (foundByIndexFile = existsSync(path.join(customTagNamespace.custom, indexFileNameFromTag))))) {
customTagNamespace.root = customTagNamespace.custom;
if (foundByIndexFile) {
fileNameFromTag = indexFileNameFromTag;
}
// Then check in defined namespace's or fallback path
} else if (!existsSync(path.join(customTagNamespace.root, fileNameFromTag))) {
if (existsSync(path.join(customTagNamespace.root, indexFileNameFromTag))) {
// Module found in folder `tag-name/index.html`
fileNameFromTag = indexFileNameFromTag;
} else if (customTagNamespace.fallback && (existsSync(path.join(customTagNamespace.fallback, fileNameFromTag)) || (foundByIndexFile = existsSync(path.join(customTagNamespace.fallback, indexFileNameFromTag))))) {
// Module found in defined namespace fallback
customTagNamespace.root = customTagNamespace.fallback;
if (foundByIndexFile) {
fileNameFromTag = indexFileNameFromTag;
}
} else if (options.namespaceFallback) {
// Last resort: try to find module by defined roots as fallback
try {
// Passing tag name without namespace, although it's only used
// for error message which in this case it's not even used.
// But passing it correctly in case in future we do something
// with tag name inside findModuleByRoot()
return findPathInRoots(tag.replace(namespace, '').replace(options.namespaceSeparator, ''), fileNameFromTag, options);
} catch {
// With disabled strict mode we will never enter here as findPathByRoot() return false
// so we don't need to check if options.strict is true
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.`);
}
} else if (options.strict) {
throw new Error(`[components] For the tag ${tag} was not found the template in the defined namespace's path ${customTagNamespace.root}.`);
} else {
return false;
}
}

// Set root to namespace root
options.root = customTagNamespace.root;
return fileNameFromTag;
}

module.exports = (tag, [namespace, fileNameFromTag], options) => findPathInNamespaces(tag, [namespace, fileNameFromTag], options);
37 changes: 37 additions & 0 deletions src/find-path-in-roots.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'use strict';

const path = require('path');
const {existsSync} = require('fs');

/**
* Find component file within all defined roots path
*
* @param {String} tag [tag name]
* @param {String} fileNameFromTag [filename converted from tag name]
* @param {Object} options [posthtml options]
* @return {String|boolean} [custom tag root where the module is found]
*/
function findPathInRoots(tag, fileNameFromTag, options) {
let root = options.roots.find(root => existsSync(path.join(root, fileNameFromTag)));

if (!root) {
// Check if module exist in folder `tag-name/index.html`
fileNameFromTag = fileNameFromTag
.replace(`.${options.fileExtension}`, '')
.concat(path.sep, 'index.', options.fileExtension);

root = options.roots.find(root => existsSync(path.join(root, fileNameFromTag)));
}

if (!root) {
if (options.strict) {
throw new Error(`[components] For the tag ${tag} was not found the template in any defined root path ${options.roots.join(', ')}`);
} else {
return false;
}
}

return path.join(root, fileNameFromTag);
}

module.exports = (tag, fileNameFromTag, options) => findPathInRoots(tag, fileNameFromTag, options);
112 changes: 6 additions & 106 deletions src/find-path.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
'use strict';

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

const folderSeparator = '.';

Expand All @@ -12,7 +13,7 @@ const folderSeparator = '.';
* @param {Object} options [posthtml options]
* @return {String|boolean}
*/
function findPathFromTagName({tag}, options) {
module.exports = ({tag}, options) => {
// Get module filename from tag name
// remove prefix "x-"
// replace dot "." with slash "/"
Expand All @@ -26,107 +27,6 @@ function findPathFromTagName({tag}, options) {
// Find module by defined namespace in options.namespaces when tag has '::'
// otherwise by defined roots in options.roots
return tag.includes(options.namespaceSeparator) ?
findPathByNamespace(tag, fileNameFromTag.split(options.namespaceSeparator), options) :
findPathByRoot(tag, fileNameFromTag, options);
}

/**
* Search for module file within namespace path
*
* @param {String} tag [tag name with namespace]
* @param {String} namespace [tag's namespace]
* @param {String} fileNameFromTag [filename converted from tag name]
* @param {Object} options [posthtml options]
* @return {String|boolean} [custom tag root where the module is found]
*/
function findPathByNamespace(tag, [namespace, fileNameFromTag], options) {
const customTagNamespace = options.namespaces.find(n => n.name === namespace.replace(options.tagPrefix, ''));

if (!customTagNamespace) {
if (options.strict) {
throw new Error(`[components] Unknown module namespace ${namespace}.`);
} else {
return false;
}
}

// Used to check module by index.html
const indexFileNameFromTag = fileNameFromTag
.replace(`.${options.fileExtension}`, '')
.concat(path.sep, 'index.', options.fileExtension);

// First check in defined namespace's custom root if module was overridden
let foundByIndexFile = false;
if (customTagNamespace.custom && (existsSync(path.join(customTagNamespace.custom, fileNameFromTag)) || (foundByIndexFile = existsSync(path.join(customTagNamespace.custom, indexFileNameFromTag))))) {
customTagNamespace.root = customTagNamespace.custom;
if (foundByIndexFile) {
fileNameFromTag = indexFileNameFromTag;
}
// Then check in defined namespace's or fallback path
} else if (!existsSync(path.join(customTagNamespace.root, fileNameFromTag))) {
if (existsSync(path.join(customTagNamespace.root, indexFileNameFromTag))) {
// Module found in folder `tag-name/index.html`
fileNameFromTag = indexFileNameFromTag;
} else if (customTagNamespace.fallback && (existsSync(path.join(customTagNamespace.fallback, fileNameFromTag)) || (foundByIndexFile = existsSync(path.join(customTagNamespace.fallback, indexFileNameFromTag))))) {
// Module found in defined namespace fallback
customTagNamespace.root = customTagNamespace.fallback;
if (foundByIndexFile) {
fileNameFromTag = indexFileNameFromTag;
}
} else if (options.namespaceFallback) {
// Last resort: try to find module by defined roots as fallback
try {
// Passing tag name without namespace, although it's only used
// for error message which in this case it's not even used.
// But passing it correctly in case in future we do something
// with tag name inside findModuleByRoot()
return findPathByRoot(tag.replace(namespace, '').replace(options.namespaceSeparator, ''), fileNameFromTag, options);
} catch {
// With disabled strict mode we will never enter here as findPathByRoot() return false
// so we don't need to check if options.strict is true
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.`);
}
} else if (options.strict) {
throw new Error(`[components] For the tag ${tag} was not found the template in the defined namespace's path ${customTagNamespace.root}.`);
} else {
return false;
}
}

// Set root to namespace root
options.root = customTagNamespace.root;
return fileNameFromTag;
}

/**
* Search for module file within all roots
*
* @param {String} tag [tag name]
* @param {String} fileNameFromTag [filename converted from tag name]
* @param {Object} options [posthtml options]
* @return {String|boolean} [custom tag root where the module is found]
*/
function findPathByRoot(tag, fileNameFromTag, options) {
let root = options.roots.find(root => existsSync(path.join(root, fileNameFromTag)));

if (!root) {
// Check if module exist in folder `tag-name/index.html`
fileNameFromTag = fileNameFromTag
.replace(`.${options.fileExtension}`, '')
.concat(path.sep, 'index.', options.fileExtension);

root = options.roots.find(root => existsSync(path.join(root, fileNameFromTag)));
}

if (!root) {
if (options.strict) {
throw new Error(`[components] For the tag ${tag} was not found the template in any defined root path ${options.roots.join(', ')}`);
} else {
return false;
}
}

return path.join(root, fileNameFromTag);
}

module.exports = (node, options) => findPathFromTagName(node, options);
findPathInNamespaces(tag, fileNameFromTag.split(options.namespaceSeparator), options) :
findPathInRoots(tag, fileNameFromTag, options);
};
Loading

0 comments on commit 9f660c7

Please sign in to comment.