UNPKG

bloom-layout

Version:
104 lines (98 loc) 2.4 kB
'use strict'; // This list is taken from https://developer.mozilla.org/en-US/docs/Web/HTML/Inline_elements const INLINE_ELEMENTS = new Set([ 'a', 'abbr', 'acronym', 'b', 'bdo', 'big', 'br', 'button', 'cite', 'code', 'dfn', 'em', 'i', 'img', 'input', 'kbd', 'label', 'map', 'object', 'q', 'samp', 'script', 'select', 'small', 'span', 'strong', 'sub', 'sup', 'textarea', 'tt', 'var' ]); module.exports = { meta: { docs: { description: 'Ensures inline tags are not rendered without spaces between them', category: 'Stylistic Issues', recommended: false }, fixable: false, schema: [ { type: 'object', properties: {}, default: {}, additionalProperties: false } ] }, create: function (context) { const elementName = node => ( node.openingElement && node.openingElement.name && node.openingElement.name.type === 'JSXIdentifier' && node.openingElement.name.name ); const isInlineElement = node => ( node.type === 'JSXElement' && INLINE_ELEMENTS.has(elementName(node)) ); const TEXT_FOLLOWING_ELEMENT_PATTERN = /^\s*\n\s*\S/; const TEXT_PRECEDING_ELEMENT_PATTERN = /\S\s*\n\s*$/; return { JSXElement: function(node) { let lastChild = null; let child = null; (node.children.concat([null])).forEach(nextChild => { if ( (lastChild || nextChild) && (!lastChild || isInlineElement(lastChild)) && (child && child.type === 'Literal') && (!nextChild || isInlineElement(nextChild)) && true ) { if (lastChild && child.value.match(TEXT_FOLLOWING_ELEMENT_PATTERN)) { context.report({ node: child, loc: child.loc, message: `Ambiguous spacing after previous element ${elementName(lastChild)}` }); } else if (nextChild && child.value.match(TEXT_PRECEDING_ELEMENT_PATTERN)) { context.report({ node: child, loc: child.loc, message: `Ambiguous spacing before next element ${elementName(nextChild)}` }); } } lastChild = child; child = nextChild; }); } }; } };