Export namespaced browser global and support config
Currently this module exports lots of global variables for the browser, this may be undesired and inflexible.
This change exports everything under a global namespaced object parseCss instead for the browser (Use "Css" to prevent conflict with a potential official API, which generally uses "CSS"). For other platforms like Node.js/CommonJs/AMD there is no difference.
Another commit adds a config object to allow the user to configure the behavior of this module, such as a custom error handle for the tokenizer and parser, which can resolve issue #41. An example usage look like:
var parseErrorHandler = parseCss.config.parseErrorHandler = function (index, token) {
parseErrorHandler.errors.push(
`Parser error at index ${index}, token ${token} on css: ${cssText}`;
);
};
parseErrorHandler.errors = [];
var cssText = /* input css string */;
var tokens = parseCss.tokenize(cssText);
// do something with parseErrorHandler.errors
Though this is still sub-optimal since a manual cleanup and a memory of the input is required before each call. For a more elegant implementation I would recommend refactoring the tokenize() and parse*() methods to be classes, so that it can be like:
const {Tokenizer: CssTokenizer} = parseCss;
const tokenizerErrorHandler = function (tokenizer, input, index, token) {
tokenizer.errors = tokenizer.errors || [];
tokenizer.errors.push(
`Parser error at index ${index}, token ${token} on css: ${input}`
);
};
var tokenizer = new CssTokenizer({errorHandler: tokenizerErrorHandler});
var tokens = tokenizer.run(/* input css string */);
/* do something with tokenizer.errors */
and for parser:
const {Parser: CssParser} = parseCss;
const parserErrorHandler = function (parser, input, index, token) {
parser.errors = parser.errors || [];
parser.errors.push(
`Parser error at token ${index}: ${token}`
);
};
var parser = new CssParser({errorHandler: parserErrorHandler});
var result = parser.parseAStylesheet(/* input css string */);
/* do something with parser.errors */
Also note that this PR doesn't include a change for README yet. A thorough discussion before applying may be needed, as this is a breaking change. Any suggestion is welcome.