diff --git a/readme.md b/readme.md index b11f3dd..2aed774 100644 --- a/readme.md +++ b/readme.md @@ -111,4 +111,4 @@ See [PostHTML Guidelines](https://github.com/posthtml/posthtml/tree/master/docs) ## Credits -Thanks to all PostHTML contributors and especially to `posthtml-extends` and `posthtml-modules` contributors, as part of code are ~~stolen~~ borrowed from these plugins. +Thanks to all PostHTML contributors and especially to `posthtml-extend` and `posthtml-modules` contributors, as part of code are ~~stolen~~ borrowed from these plugins. diff --git a/src/index.js b/src/index.js index 83e5409..d2b9509 100644 --- a/src/index.js +++ b/src/index.js @@ -53,7 +53,7 @@ function processNodes(tree, options, messages) { const html = parseToPostHtml(fs.readFileSync(filePath, options.encoding)); - const {attributes, defaultLocals} = parseLocals(options, node, html); + const {attributes, locals} = parseLocals(options, node, html); options.expressions.locals = attributes; @@ -75,7 +75,7 @@ function processNodes(tree, options, messages) { const nodeAttrs = parseAttrs(node.content[index].attrs); Object.keys(attributes).forEach(attr => { - if (typeof defaultLocals[attr] === 'undefined') { + if (typeof locals[attr] === 'undefined') { if (['class'].includes(attr)) { nodeAttrs[attr].push(attributes[attr]); } else if (['style'].includes(attr)) { @@ -109,26 +109,56 @@ function processNodes(tree, options, messages) { function parseLocals(options, {attrs}, html) { let attributes = {...attrs}; + // Handle attributes to be merged with default + // only for Array or Objects + const mergeAttributeWithDefault = []; + Object.keys(attributes).forEach(attribute => { + if (attribute.startsWith('merge:')) { + const newAttributeName = attribute.replace('merge:', ''); + attributes[newAttributeName] = attributes[attribute]; + delete attributes[attribute]; + mergeAttributeWithDefault.push(newAttributeName); + } + }); + + // Parse JSON attributes Object.keys(attributes).forEach(attribute => { try { // Use merge() ? - attributes = {...attributes, ...JSON.parse(attributes[attribute])}; + const parsed = JSON.parse(attributes[attribute]); + if (attribute === 'locals') { + if (mergeAttributeWithDefault.includes(attribute)) { + attributes = merge(attributes, parsed); + } else { + Object.assign(attributes, parsed); + } + } else { + attributes[attribute] = parsed; + } } catch {} }); delete attributes.locals; + // Merge with global attributes = merge(options.expressions.locals, attributes); // Retrieve default locals from +