isFirstNested.js 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. 'use strict';
  2. const { isComment, hasSource } = require('./typeGuards');
  3. /**
  4. * @param {import('postcss').Node} statement
  5. * @returns {boolean}
  6. */
  7. module.exports = function isFirstNested(statement) {
  8. const parentNode = statement.parent;
  9. if (parentNode === undefined || parentNode.type === 'root') {
  10. return false;
  11. }
  12. if (statement === parentNode.first) {
  13. return true;
  14. }
  15. /*
  16. * Search for the statement in the parent's nodes, ignoring comment
  17. * nodes on the same line as the parent's opening brace.
  18. */
  19. const parentNodes = parentNode.nodes;
  20. if (!parentNodes) {
  21. return false;
  22. }
  23. const firstNode = parentNodes[0];
  24. if (!firstNode) {
  25. return false;
  26. }
  27. if (
  28. !isComment(firstNode) ||
  29. (typeof firstNode.raws.before === 'string' && firstNode.raws.before.includes('\n'))
  30. ) {
  31. return false;
  32. }
  33. if (!hasSource(firstNode) || !firstNode.source.start) {
  34. return false;
  35. }
  36. const openingBraceLine = firstNode.source.start.line;
  37. if (!firstNode.source.end || openingBraceLine !== firstNode.source.end.line) {
  38. return false;
  39. }
  40. for (const [index, node] of parentNodes.entries()) {
  41. if (index === 0) {
  42. continue;
  43. }
  44. if (node === statement) {
  45. return true;
  46. }
  47. if (
  48. !isComment(node) ||
  49. (hasSource(node) && node.source.end && node.source.end.line !== openingBraceLine)
  50. ) {
  51. return false;
  52. }
  53. }
  54. /* istanbul ignore next: Should always return in the loop */
  55. return false;
  56. };