usercss-meta icon indicating copy to clipboard operation
usercss-meta copied to clipboard

Initial Commit

Open Mottie opened this issue 7 years ago • 12 comments

  • This first version only supports parsing the metadata block of usercss styles.
  • It has not yet been published to npm - we can do it once everyone feels that it's ready.
  • Collaborators please review and feel free to make any modifications as needed.

Mottie avatar Jan 08 '18 18:01 Mottie

It's nice to split usercss parser out from the extension so other people can reuse it. However, I'm not sure what is the purpose of this library. If it is intended to be used by others, it shouldn't include such heavy dependencies like accord and stylus.

If this library is going to be the "usercss core" part of Stylus extension, I think we can split it into two different libraries:

  1. The metadata parser, including color parser (and maybe semver). If someone just need to parse the metadata, they can use this library.

  2. The usercss library itself, which depends on metadata parser. Users can extend it with multiple preprocessor, for example:

    const {Usercss} = require("usercss"); // remove "-parser" suffix
    const usercss = new Usercss;
    usercss.addPreprocessor("stylus", {
    	preprocess: (source, variables) => {...}
    });
    
    let userstyle = usercss.parseMeta(usercssSourceCode);
    // ... do something to userstyle.usercssData ...
    userstyle = await usercss.buildSections(userstyle); // or usercss.buildCode
    userstyle.sections.forEach(s => console.log(s.code)); // read-to-use CSS code
    

If we are just going to pull out the parser part of usercss, we can remove everything related to buildCode().

semver dependency should be removed since it is only used for validation. We can use regexp instead.

eight04 avatar Jan 08 '18 19:01 eight04

My original idea was to split out the full parser, but since it's integrated with CSSLint, I switched to only parsing the metadata... I just removed accord and stylus as a dependency. Maybe we can think about building a full parser in the future.

Mottie avatar Jan 08 '18 19:01 Mottie

semver dependency should be removed since it is only used for validation. We can use regexp instead.

That's true too! 😸

Mottie avatar Jan 08 '18 19:01 Mottie

I didn't want to modify the usercss too much to make it easier to keep up-to-date with the main file in the Stylus repo. Maybe we should forget about that limitation and clean up the unnecessary code.

Mottie avatar Jan 08 '18 19:01 Mottie

make it easier to keep up-to-date with the main file in the Stylus repo

It might be better if Stylus can use this library. E.g.

// stylus/js/usercss.js
const {Parser} = require("parse-usercss");
const parser = new Parser;
// override builtin validators
parser.onValidate("url", (key, value) => {
	// custom validator for URLs
});
parser.onValidate("version", (key, value) => {
	// stylus uses semver to validate version
});
parser.onValidateVar("color", (key, type, label, value) => {
	// custom validator for colors
});
parser.on("end", meta => {
	// override null-check for meta.version, meta.namespace, and meta.name
});

// in buildMeta()
const meta = parser.parse(metadataSourceCode);
style.usercssData = meta;
...

I think @tophf can tell which APIs are needed.

eight04 avatar Jan 08 '18 20:01 eight04

Well, like I said, I'm not interested in developing external tools, but I agree it'd be nice if you end up with something that may be usable in Stylus as-is. All Stylus needs is for the parser to produce sections and errors, see moz-parser.js:78. The errors do not necessarily prevent the output of sections, at least Stylus allows saving and live-reloading of usercss with syntax errors, the errors being separately displayed (in addition to the lint report).

Ah, and your parser should be really fast because currently the new reusable cache in csslint produces the mozparser's output in just a few milliseconds on subsequent saving while the user edits the style. This is very important especially for the, hopefully, upcoming [automatic] preview-while-editing feature.

P.S. for the meta block, I don't know, simply return the parsed data and the errors array.

tophf avatar Jan 09 '18 07:01 tophf

If we can achieve a dependency-free parser, integration into stylus could be as simple as adding a git submodule that points to this repo. That way you wouldn't even need a build step in stylus, @tophf. Thought, I'd certainly welcome if stylus would depend on this module using package.json.

silverwind avatar Jan 12 '18 15:01 silverwind

On second thought, I don't see it as being useful in Stylus because Stylus needs CSSLint to show meaningful error messages when trying to install/save a broken style. A stand-alone simple parser serves another purpose.

tophf avatar Jan 12 '18 21:01 tophf

On second thought, I don't see it as being useful in Stylus because Stylus needs CSSLint to show meaningful error messages when trying to install/save a broken style. A stand-alone simple parser serves another purpose.

I have to object. I think the concerns of parsing the usercss header and linting CSS should be separated, unless the parsers can output a lintable format which pretty much means it must output a AST, the basis of all modern linters.

silverwind avatar Jan 12 '18 21:01 silverwind

Well, it's not about semantics or idealistic should-be's, it's about practical usefulness. The fact is, the current implementation in Stylus is useful as is, whereas a lint-less parser is not as it would require an additional linting pass, which is a waste of resources and time.

tophf avatar Jan 12 '18 22:01 tophf

Currently, Stylus processes usercss in following steps:

  1. Parse usercss metadata. Extract information like name, variables, preprocessor, etc.
  2. Variables might be changed by users.
  3. If there is a preprocessor, run the preprocessor (e.g. compile stylus-lang into CSS).
  4. Parse the CSS code with CSSLint. Extract @document rules and split the code into multiple sections.
  5. If there is a postprocessor, run the postprocessor (e.g. insert CSS variables to each section).

If we make this library as a simple metadata parser, Stylus can use it in the first step and others can also use it to extract metadata information.

I agree that it is not very useful to include entire parser/compiler. The compiler would probably only be used by extensions (e.g. Stylus).


integration into stylus could be as simple as adding a git submodule that points to this repo

Stylus keeps libraries in the repo. We just have to browserify/rollup the module to a single dist file.

eight04 avatar Jan 13 '18 02:01 eight04

Stylus keeps libraries in the repo. We just have to browserify/rollup the module to a single dist file.

Yeah, or keep the parser in ES5 and use a UMD header so it's importable everywhere.

silverwind avatar Jan 14 '18 10:01 silverwind