Вопрос по parsing, javascript, css, node.js – CSS парсер для JavaScript?

20

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

Я хотел бы проанализировать блоб CSS в AST, чтобы я мог добавить префиксы к определенным директивам CSS.

Есть ли парсер CSS для JavaScript или Node, который это сделает?

Я искал NPM. Единственный полезный результат, который я нашел, - этопарсер Пб, но он основан на потоке и выглядит так, как будто мне нужно написать свой собственный эмиттер для каждого узла CSS.

Update: Я также нашелJSCSSP, но у него нет документации ...

В самом деле? Downvoted? С & APOS; мес. a paid nerd
Нет причин, чтобы понизить это. Вы кого-нибудь недавно расстроили? Gareth

Ваш Ответ

6   ответов
3

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-парсера:

It is lightweight. It outputs easy to understand javascript object. No complex AST. It is battle tested(and unit tested also) and constantly used in our products(JotForm Form Designer). It supports media queries, keyframes and font-face rules. It preserves comments while parsing.
10

Update: Я ранее упомянул Аксспс, который глючит, похоже, заброшен. Очевидно, чтомодуль 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;
}
Это именно то, что я искал - добавить область действия к правилам.
Кстати, сразу после того, как вы обновили это (24 июля 2013 года), проект JSCSSP был обновлен с множеством исправлений -glazman.org/JSCSSP/news.html
2
Edit

что использовал эту библиотеку, которая была достаточно легкой для моей реализации (предоставленной вKemal Dağответ). Другие варианты были слишком тяжелыми для реализации на стороне клиента, за которой я следовал.

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

Original Content

a paid nerdОригинальный ответ работал великолепно, пока я не нажал медиа-запросы.

Я должен был добавить некоторую рекурсию, и это то, чем я закончил.

Прости меня за 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<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'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;
}
5

МЕНЬШЕ, Хотя это в первую очередь (фантастическое) расширение CSS, парсер LESS дает вам доступ к AST.

Чистая таблица стилей CSS также является допустимой таблицей стилей LESS, поэтому вы можете начать с того, что у вас есть сейчас, и легко перейти к LESS & apos; расширения.

Просто обновление для новичков: похоже, что проект LESS не будет поддерживать прямой доступ к парсеру в будущем:lesscss.org/usage/index.html#programmatic-usage, Конечно, вы всегда можете просто выбрать текущую / прошлую версию и использовать ее.
4

JSDOM использованияCSSOM.

Кажется, что эта библиотека на треть меньше размера JSCSSP с точки зрения строк кода, вероятно, из-за всего, что она не пытается поддерживать. Для проектов только HTML5 это путь.
Это потрясающе, мне было интересно, была ли прямая объектная модель вместо этих безумных AST, которые есть во всех других библиотеках.
1
Спасибо! Я тоже это понял. a paid nerd

Похожие вопросы