Page MenuHomePhabricator

Integrate TemplateStyles errors with CodeEditor
Open, LowPublic

Description

Upon save, TemplateStyles will say something like Invalid or unsupported value for property foo at line 12 character 34. This is not super convenient because

  1. it only happens on save, not preview (or real-time as the normal CSS linting for CodeEditor, although I guess that would be too expensive)
  2. the user has to manually locate the position
  3. which is made more confusing by the fact that CodeEditor uses 0-based line positions and css-sanitizer uses 1-based ones.

There should be a way to trigger the errors without saving (so that the user does not have to bother with edit summary etc. before checking whether the edit is valid) and the errors should ideally appear as CodeEditor annotations, but if not, they should at least have some button to bring the cursor to the position of the error.

Event Timeline

it only happens on save, not preview

It does happen on preview, the errors are displayed just under the text that says "This is only a preview; your changes have not yet been saved!". Note TemplateStyles doesn't control the positioning or formatting, that's where and how EditPage displays errors from ParserOutput::getWarnings().

(or real-time as the normal CSS linting for CodeEditor, although I guess that would be too expensive)

Real-time would require round-trips to the server (e.g. to https://sv.wikipedia.org/w/api.php?action=parse&prop=parsewarnings&title=Template:Whatever/style.css&contentmodel=sanitized-css&text=.foo%20{%20color:%20octarine;%20}). Do-able, but it may be a bit much.

Or porting css-sanitizer plus TemplateStyles's adjustments to JavaScript and integrating it to CodeEditor, I suppose. I wouldn't hold my breath.

which is made more confusing by the fact that CodeEditor uses 0-based line positions and css-sanitizer uses 1-based ones.

Not that it makes much of a difference, but it may be that CodeEditor is considering that cursor position 0 comes before character 1, while cursor position 1 comes between characters 1 and 2.

and the errors should ideally appear as CodeEditor annotations

If you can figure out how to do that, it might also be useful to figure out how to hide CodeEditor's own annotations. On the random page on my localhost I'm using for testing, CodeEditor is complaining that grid-area is unrecognized while css-sanitizer will recognize it.

It does happen on preview, the errors are displayed just under the text that says "This is only a preview; your changes have not yet been saved!".

You are right, when I disable live preview, I can see it just fine. Filed as T190120: Parse warnings not visible with live preview.

As for CodeEditor integration, I suppose the first step would be to get parse warnings in a structured format, where the line/column are separate properties. Not sure what's the least painful way to do that. Expose ParserOutput extension data in ApiParse and have TemplateStyles set error positions in extension data, keyed by error text? Make ParserOutput accept and return Message objects as warnings, and then call the api with errorformat=raw? (It's a slightly annoying property of the error formatting system btw that you can't get the final message and the parameters at the same time.)

If you can figure out how to do that, it might also be useful to figure out how to hide CodeEditor's own annotations. On the random page on my localhost I'm using for testing, CodeEditor is complaining that grid-area is unrecognized while css-sanitizer will recognize it.

The bruteforce approach is to add some kind of hook for language selection (the setMode call in jquery.codeEditor.js), copy mode-css.js, discard most of worker-css.js and replace it with a parse API call (could be periodic or controlled by some UI element or triggered just once if we are in a preview). The worker just needs to return a list of errors (position, text, serverity). There might be a more intelligent way of modifying the CSS worker on the fly, couldn't tell at a glance. It does include some style stuff (e.g. warn on empty rules) that would be useful to keep, although not really important.

As for CodeEditor integration, I suppose the first step would be to get parse warnings in a structured format, where the line/column are separate properties. Not sure what's the least painful way to do that. Expose ParserOutput extension data in ApiParse and have TemplateStyles set error positions in extension data, keyed by error text? Make ParserOutput accept and return Message objects as warnings, and then call the api with errorformat=raw?

I'd say add optional locational parameters to ParserOutput::addWarning() (and some way to fetch that data, of course), rather than trying to assume the line and column are at particular locations in a Message's parameter list or trying to deal with a single extension's extension data.

(It's a slightly annoying property of the error formatting system btw that you can't get the final message and the parameters at the same time.)

We could probably allow something like errorformat=wikitext|raw to include both in the output. File a separate task requesting it if you want.

ggellerman lowered the priority of this task from Medium to Low.May 8 2018, 6:11 PM