Analysez CSS en JavaScript / jQuery

J'essaie d'implémenter l'analyse de CSS en JavaScript afin que:

a { color: red; } 

Est analysé dans l'objet:

 { 'a' { 'color': 'red' } } 

D'abord, existe-t-il une bibliothèque JavaScript / jQuery que je peux utiliser?

Ma mise en œuvre est assez basique, donc je suis sûr que ce n'est pas trompeur par tous les moyens. Par exemple, cela fonctionne bien pour les CSS de base, mais pour une propriété du type:

 background: url(data:image/png;base64, ....); 

Il échoue parce que j'utilise split(';') pour séparer les property:value paires de property:value . Ici ; Se produit dans la value , donc il se divise à ce point aussi.

Y a-t-il une autre façon de le faire?

Voici le code:

 parseCSS: function(css) { var rules = {}; css = this.removeComments(css); var blocks = css.split('}'); blocks.pop(); var len = blocks.length; for (var i = 0; i < len; i++) { var pair = blocks[i].split('{'); rules[$.trim(pair[0])] = this.parseCSSBlock(pair[1]); } return rules; }, parseCSSBlock: function(css) { var rule = {}; var declarations = css.split(';'); declarations.pop(); var len = declarations.length; for (var i = 0; i < len; i++) { var loc = declarations[i].indexOf(':'); var property = $.trim(declarations[i].substring(0, loc)); var value = $.trim(declarations[i].substring(loc + 1)); if (property != "" && value != "") rule[property] = value; } return rule; }, removeComments: function(css) { return css.replace(/\/\*(\r|\n|.)*\*\//g,""); } 

Merci!

Il y a un analyseur CSS écrit en Javascript appelé JSCSSP

Vous pouvez facilement utiliser le CSSOM du navigateur pour analyser CSS:

 var rulesForCssText = function (styleContent) { var doc = document.implementation.createHTMLDocument(""), styleElement = document.createElement("style"); styleElement.textContent = styleContent; // the style will only be parsed once it is added to a document doc.body.appendChild(styleElement); return styleElement.sheet.cssRules; }; 

Pour chaque règle renvoyée, vous pouvez regarder les propriétés dans rule.style . Voir http://jsfiddle.net/v2JsZ/ pour un exemple.

Pour écrire l'analyseur le plus insensé, suivez les règles exactes pour la tokenisation et la grammaire CSS telle que définie dans la spécification. Notez que vous ne devez pas implémenter les spécifications par l'encre. Vous pouvez commencer avec de petites pièces et CSS que vous rencontrerez très probablement, puis vous développerez à partir de là. Encore mieux, sautez tout le processus et allez avec la solution @ Matthew, à moins que ce ne soit un exercice d'apprentissage.

Il existe différents scanners lexicaux et générateurs d'analyseurs disponibles pour JavaScript. Toute la grammaire est disponible sur le site Web du w3. Pourquoi re-travailler lorsque vous pouvez simplement l'utiliser et que les générateurs d'analyseur génèrent l'analyseur en JavaScript.

  1. Jison
  2. Peg.js
  3. Cruiser.Parse
  4. McLexer
  5. JS / CC

Les règles de production pour CSS sont données ci-dessous.

 stylesheet : [ CHARSET_SYM STRING ';' ]? [S|CDO|CDC]* [ import [ CDO S* | CDC S* ]* ]* [ [ ruleset | media | page ] [ CDO S* | CDC S* ]* ]* ; import : IMPORT_SYM S* [STRING|URI] S* media_list? ';' S* ; media : MEDIA_SYM S* media_list LBRACE S* ruleset* '}' S* ; media_list : medium [ COMMA S* medium]* ; medium : IDENT S* ; page : PAGE_SYM S* pseudo_page? '{' S* declaration? [ ';' S* declaration? ]* '}' S* ; pseudo_page : ':' IDENT S* ; operator : '/' S* | ',' S* ; combinator : '+' S* | '>' S* ; unary_operator : '-' | '+' ; property : IDENT S* ; ruleset : selector [ ',' S* selector ]* '{' S* declaration? [ ';' S* declaration? ]* '}' S* ; selector : simple_selector [ combinator selector | S+ [ combinator? selector ]? ]? ; simple_selector : element_name [ HASH | class | attrib | pseudo ]* | [ HASH | class | attrib | pseudo ]+ ; class : '.' IDENT ; element_name : IDENT | '*' ; attrib : '[' S* IDENT S* [ [ '=' | INCLUDES | DASHMATCH ] S* [ IDENT | STRING ] S* ]? ']' ; pseudo : ':' [ IDENT | FUNCTION S* [IDENT S*]? ')' ] ; declaration : property ':' S* expr prio? ; prio : IMPORTANT_SYM S* ; expr : term [ operator? term ]* ; term : unary_operator? [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* | TIME S* | FREQ S* ] | STRING S* | IDENT S* | URI S* | hexcolor | function ; function : FUNCTION S* expr ')' S* ; /* * There is a constraint on the color that it must * have either 3 or 6 hex-digits (ie, [0-9a-fA-F]) * after the "#"; eg, "#000" is OK, but "#abcd" is not. */ hexcolor : HASH S* ;