index.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. const { isVElement } = require('..')
  2. class StyleVariablesContext {
  3. /**
  4. * @param {RuleContext} context
  5. * @param {VElement[]} styles
  6. */
  7. constructor(context, styles) {
  8. this.context = context
  9. this.styles = styles
  10. /** @type {VReference[]} */
  11. this.references = []
  12. /** @type {VExpressionContainer[]} */
  13. this.vBinds = []
  14. for (const style of styles) {
  15. for (const node of style.children) {
  16. if (node.type === 'VExpressionContainer') {
  17. this.vBinds.push(node)
  18. for (const ref of node.references.filter(
  19. (ref) => ref.variable == null
  20. )) {
  21. this.references.push(ref)
  22. }
  23. }
  24. }
  25. }
  26. }
  27. }
  28. module.exports = {
  29. getStyleVariablesContext,
  30. StyleVariablesContext
  31. }
  32. /** @type {WeakMap<VElement, StyleVariablesContext>} */
  33. const cache = new WeakMap()
  34. /**
  35. * Get the style vars context
  36. * @param {RuleContext} context
  37. * @returns {StyleVariablesContext | null}
  38. */
  39. function getStyleVariablesContext(context) {
  40. const sourceCode = context.getSourceCode()
  41. const df =
  42. sourceCode.parserServices.getDocumentFragment &&
  43. sourceCode.parserServices.getDocumentFragment()
  44. if (!df) {
  45. return null
  46. }
  47. const styles = df.children.filter(
  48. /** @returns {e is VElement} */
  49. (e) => isVElement(e) && e.name === 'style'
  50. )
  51. if (styles.length === 0) {
  52. return null
  53. }
  54. let ctx = cache.get(styles[0])
  55. if (ctx) {
  56. return ctx
  57. }
  58. ctx = new StyleVariablesContext(context, styles)
  59. cache.set(styles[0], ctx)
  60. return ctx
  61. }