26

2018年の更新:この質問はPostCSSが存在するずっと前に尋ねられたもので、おそらくそれを使用したでしょう。

特定のCSSディレクティブにプレフィックスを追加できるように、CSSのblobをASTに解析したいと思います。

これを行うJavaScriptまたはノード用のCSSパーサーはありますか?

NPMを検索しました。私が見つけた唯一の有用な結果はparser-libですが、これはストリームベースであり、CSSノードごとに独自のエミッターを作成する必要があるようです。

更新:JSCSSPも見つかりましたが、ドキュメントがありません...

4

7 に答える 7

11

更新:先ほど、バグのあるJSCSSPは放棄されているようです。明らかに、NPMのcssモジュールが最適です。

css = require 'css'

input = '''
  body {
    font-family: sans-serif;
  }
  #thing.foo p.bar {
    font-weight: bold;
  }
'''

obj = css.parse input
sheet = obj.stylesheet

for rule in sheet.rules
  rule.selectors = ('#XXX ' + s for s in rule.selectors)

console.log css.stringify(obj)

出力:

#XXX body {
  font-family: sans-serif;
}
#XXX #thing.foo p.bar {
  font-weight: bold;
}
于 2012-06-09T19:51:40.933 に答える
5

また、言及する価値があるのはLESSです。これは主にCSSの(素晴らしい)拡張機能ですが、LESSパーサーを使用するとASTにアクセスできます。

純粋なCSSスタイルシートも有効なLESSスタイルシートであるため、現在使用しているものから始めて、LESSの拡張機能を簡単に使用できます。

于 2013-04-17T03:36:29.583 に答える
5

これが私たちのオープンソースCSSパーサーcss.jsです

簡単な解析例を次に示します。

<script type="text/javascript">
    var cssString = ' .someSelector { margin:40px 10px; padding:5px}';
    //initialize parser object
    var parser = new cssjs();
    //parse css string
    var parsed = parser.parseCSS(cssString);

    console.log(parsed);
</script>

編集後に解析されたデータ構造をCSS文字列に文字列化するには

var newCSSString = parser.getCSSForEditor(parsed);

CSSパーサーの主な機能は次のとおりです。

  • 軽量です。
  • わかりやすいjavascriptオブジェクトを出力します。複雑なASTはありません。
  • バトルテスト済み(およびユニットテスト済み)であり、当社の製品(JotForm Form Designer)で常に使用されています。
  • メディアクエリ、キーフレーム、フォントフェイスルールをサポートしています。
  • 解析中にコメントを保持します。
于 2015-02-18T19:57:59.490 に答える
4

その価値のために、JSDOMCSSOMを使用します。

于 2012-11-12T06:18:57.827 に答える
2

編集

私は自分の実装に十分軽いこのライブラリを使用することになりました(Kemal Dağの回答で提供されています)。他のオプションは、私が求めていたクライアント側の実装には重すぎました。

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

オリジナルコンテンツ

a paid nerd私がメディアクエリをヒットするまで、の元の答えはうまくいきました。

私はいくつかの再帰を追加する必要がありました、そしてこれは私が最終的に得たものです。

TypeScriptを許してください。

TypeScriptの実装

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<CSS.Rule|CSS.Media> = stylesheet.rules;
    let prefix = `[data-id='sticky-container-${this.parent.id}']`;

    // Append our container scope to rules
    // Recursive rule appender
    let ruleAppend = (rules: Array<CSS.Rule|CSS.Media>) => {
      rules.forEach(rule => {
        let cssRule = <CSS.Rule>rule;
        let mediaRule = <CSS.Media>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'izedVanillaJSの実装

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;
}
于 2018-02-23T23:31:19.793 に答える
2

外部のCSSパーサーを使用する必要はありません。ネイティブのCSSパーサーを使用できます。

   
var sheetRef=document.getElementsByTagName("style")[0];

console.log("----------------list of  rules--------------");
for (var i=0; i<sheetRef.sheet.cssRules.length; i++){


var sheet = sheetRef.sheet ? sheetRef.sheet : sheetRef.styleSheet;


if (sheet.cssRules.length > 0) {
//console.log(sheet.cssRules[i]);
  console.log(sheet.cssRules[i].selectorText);
  console.log(sheet.cssRules[i].cssText);

                }}
.red{

color:red;
}

ルールを挿入するには

var sheetRef=document.getElementsByTagName("style")[0];
var sheet = sheetRef.sheet ? sheetRef.sheet : sheetRef.styleSheet;
sheet.insertRule('.foo{color:red;}', 0);

バージョン9より前のIEを除くすべてのブラウザのルールを削除するには

var sheetRef=document.getElementsByTagName("style")[0];
var sheet = sheetRef.sheet ? sheetRef.sheet : sheetRef.styleSheet;
sheet.removeRule (0);

バージョン9より前のIEを除くすべてのブラウザのルールを削除するには

var sheetRef=document.getElementsByTagName("style")[0];
var sheet = sheetRef.sheet ? sheetRef.sheet : sheetRef.styleSheet;
sheet.deleteRule (0);

メディアを追加するには

  function AddScreenMedia () {
            var styleTag = document.getElementsByTagName("style")[0];

                // the style sheet in the style tag
            var sheet = styleTag.sheet ? styleTag.sheet : styleTag.styleSheet;

            if (sheet.cssRules) {   // all browsers, except IE before version 9
                var rule = sheet.cssRules[0];
                var mediaList = rule.media;

                alert ("The media types before adding the screen media type: " + mediaList.mediaText);
                mediaList.appendMedium ("screen");
                alert ("The media types after adding the screen media type: " + mediaList.mediaText);
            }
            else {  // Internet Explorer before version 9
                    // note: the rules collection does not contain the at-rules
                alert ("Your browser does not support this example!");
            }
        }
  @media print {
            body {
                font-size: 13px;
                color: #FF0000;
            }
          }
some text
<button onclick="AddScreenMedia ();">Add screen media</button>

ルールを取得するには

 
var sheetRef=document.getElementsByTagName("style")[0];

console.log("----------------list of  rules--------------");
for (var i=0; i<sheetRef.sheet.cssRules.length; i++){


var sheet = sheetRef.sheet ? sheetRef.sheet : sheetRef.styleSheet;


if (sheet.cssRules.length > 0) {
//console.log(sheet.cssRules[i]);
  console.log(sheet.cssRules[i].selectorText);
  console.log(sheet.cssRules[i].cssText);
  
  console.log(sheet.cssRules[i].style.color)
  console.log(sheet.cssRules[i].style.background)
    console.log(sheet.cssRules[i].style)

                }}
.red{

color:red;
background:orange;
}
<h1>red</h1>

于 2020-05-07T05:19:41.220 に答える
1

http://www.glazman.org/JSCSSP/

http://jsfiddle.net/cYEgT/

sheetASTのようなものです。

于 2012-06-09T19:40:30.103 に答える