CSS parser for JavaScript?

后端 未结 7 1093
既然无缘
既然无缘 2020-12-13 19:45

Update 2018: This question was asked long before PostCSS existed, and I would have probably used that.

I\'d like to par

7条回答
  •  心在旅途
    2020-12-13 20:00

    Edit

    I ended up using this library which was light enough for my implementation (provided in Kemal Dağ's answer). Other options were too heavy for the client-side implementation I was after.

    https://github.com/jotform/css.js

    Original Content

    a paid nerd's original answer worked great until I hit media queries.

    I had to add some recursion and this is what I ended up with.

    Forgive me for the TypeScript.

    TypeScript Implementation

    private scopeCSS(css: string): CSS.Stylesheet {
      let ast: CSS.Stylesheet = CSS.parse(css);
      let stylesheet: CSS.StyleRules|undefined = ast.stylesheet;
      if (stylesheet) {
        let rules: Array = stylesheet.rules;
        let prefix = `[data-id='sticky-container-${this.parent.id}']`;
    
        // Append our container scope to rules
        // Recursive rule appender
        let ruleAppend = (rules: Array) => {
          rules.forEach(rule => {
            let cssRule = rule;
            let mediaRule = rule;
            if (cssRule.selectors !== undefined) {
              cssRule.selectors = cssRule.selectors.map(selector => `${prefix} ${selector}`);
            }
            if (mediaRule.rules !== undefined) {
              ruleAppend(mediaRule.rules);
            }
          });
        };
    
        ruleAppend(rules);
      }
      return ast;
    }
    

    Babel'ized Vanilla JS Implementation

    function scopeCSS(css, prefix) {
      var ast = CSS.parse(css);
      var stylesheet = ast.stylesheet;
      if (stylesheet) {
        var rules = stylesheet.rules;
        // Append our container scope to rules
        // Recursive rule appender
        var ruleAppend = function(rules) {
          rules.forEach(function(rule) {
            if (rule.selectors !== undefined) {
              rule.selectors = rule.selectors.map(function(selector) {
                return prefix + " " + selector;
              });
            }
            if (rule.rules !== undefined) {
              ruleAppend(rule.rules);
            }
          });
        };
        ruleAppend(rules);
      }
      return ast;
    }
    

提交回复
热议问题