-
Notifications
You must be signed in to change notification settings - Fork 305
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Include both CSSLint and stylelint #150
Conversation
Those who just install styles don't need a better linter and the significant increase of the extension size. Those authors who don't use advanced features provided by StyleLint would not enjoy the increase in the time needed to load and initialize the editor. The solution can be creating an additional editor extension so that Stylus would use it for its edit action. I've already explained all this when StyleLint was suggested. |
On the other hand, the zip increase is only 500kB -> 1MB, which is kinda tolerable. And the increased load/parse times may not be an issue for those who absolutely need StyleLint. So we can still use this PR if you add an option to use CSSLint or StyleLint in the editor. The corresponding script(s) elements should be added based on the option value. And of course the editor should be able to use both linters. |
Ah, since there are CodeMirror addons that depend on linter script the entire script loading process should be programmatic, I guess, something like this |
Tolerable is a step up from unacceptable. The size increase is pretty drastic for something that'd only end up as an option though, no? I don't see how it's worth it if we're not committed to making it the default. Whether that's worth doing is apparently debatable. How noticeable are any speed issues? I tested briefly, and didn't see anything too out of whack. I see a few necessary overwrites right off the bat with StyeLint. Whatever is used will need tweaks, but with CSSlint, we're basically forking an abandoned project to maintain locally, whereas StyleLint can be expected to be generally maintained, correct? Ultimately, you deal with most of the CSSLint bullshit tophf, so it's your call, but I'd think that a size increase this drastic would only be warranted for integral, default functionality, not an optional feature which'll never be utilized by the majority of users. |
Stylelint is more actively maintained and also supports a lot of the newer css changes like variables and it'll work with the stylus preprocessor (for issue #134) out of the box. I know the bundle file is huge, but I think with a bit of work removing unnecessary code, we could bring that size down. The problem would be duplicating the modifications on updated versions of Stylelint. Also, stylelint doesn't include a worker like CSSLint did, so there may be some performance differences. |
Well, the majority of users don't even open the editor hence my initial reluctance... As for the performance, my i7 PC or yours are probably faster than the average so I'm judging by the numbers in devtools profiler: StyleLint takes as much time to load as the editor itself, linting is several times slower compared to CSSLint. With large styles and slower computers this difference will be noticeable. |
CSSLint doesn't use service workers, it's just a trivial code cosmetics that makes the script easier to include in a service worker. We don't use service workers as well. The performance difference is inherent because CSSLint is much more simple. |
Hmm, maybe we could have a toggle to enable/disable active linting, and a button to check the linting on click. I'll look at it some more tomorrow. |
For advanced authoring it's better to implement the external editor support. Currently the development of that feature is stalled for unknown reason. |
To clarify my stance: we can switch to StyleLint as the default linter as long as there's an option to switch to CSSLint. Also, it'd be reasonable to add a config dialog to choose the rules using checkboxes (and, ideally, with an import of a standard StyleLint config format). |
If we do end up switching to StyleLint as the default, here's the immediately obvious bugs. "Write a new style" opens to an "unexpected empty source" error, non-typical selectors without Examples:
Moz-format import/export are also broken. I do remember back in the day, using Freestyler on a dual core, I had to disable the persistent validator. Not even sure what they were using, but the CPU usage was a bitch. The ability to revert to CSSLint should suffice, but options to completely disable, or only validate on save, might be useful to some. Pardon the ignorance, as always, but how efficient is the persistent validator in general? Is it a blunt instrument, constantly parsing the entire code, or is it only checking newly added code that hasn't already been validated? Even then, I would think it could only check for a few errors until matching brackets and then run the gambit. Not suggesting we could or should reinvent the validator, but I'm curious how resource intensive it is needlessly. |
All linters validate the entire style. I've been thinking today about limiting the area, but it's not trivial so I've postponed the thought until the editor is rewritten. |
I can change the config settings to ignore this. This would also mean modifying the "block-no-empty" rule (e.g.
This is the typical behavior of the linter... it's hard to guess what selectors someone will use. These can be changed to warnings instead of errors.
I was testing this update with both GitHub-Dark and Stackoverflow-Dark. The "unexpected longhand/shorthand" issues are actually valid in this case. I could also change these to be warnings.
If I paste the scrollbar code into the stylelint demo, these errors pop up, so it's an issue with stylelint which is interesting since it appears to actually be included in their keyword list. I opened an issue - stylelint/stylelint#2810. |
I didn't extensively look at the It is pretty much a "blunt instrument" otherwise in that it checks the entire section on change; so it isn't too bad when I edit Stackoverflow-Dark with 40+ sections. It isn't too bad when I edit GitHub-Dark either... It doesn't seem that slow on my system, although I do have a older i7 quad core.
@tophf Do you mean add settings for standard rules or stylistic rules? or both? Maybe allowing the user to copy/paste their config JSON file into a separate textarea would be easier? |
I mean whatever makes sense. I don't use StyleLint but I know it has lots of rules which obviously won't suit everyone. In CSSLint we've enabled just four rules. Not sure the other ones are useful but maybe I'll add a config dialog for CSSLint as well. Someday. |
@tophf I've been working on a dropdown select on the edit.html page, I can't seem to get the (dynamically) user selected linter to update... When the dropdown is modified, the case 'linter':
if (value !== null && (editors.lastActive || editors[0])) {
if (prefs.get(el.id) !== value) {
prefs.set(el.id, value || 'csslint');
}
CodeMirror.signal(editors.lastActive || editors[0], "change");
// save();
}
break; If I signal a change on
The call to |
I'd expect you would do something similar to |
What about "tree shaking" to make the bundle smaller? I find it hard to believe that all that code is needed. |
Well, I've tried webpack, browserify and rollup. The first two methods always seems to result in files 3+Mb in size - like it wasn't tree shaking at all. And, I just can't seem to get rollup to include node module files (even when I include |
Ok, I think it's ready for review now... some notes:
|
CodeMirror instance in a popup function like the one used for import-export, yes. And js linter addon (IIRC it's tiny), dynamically loaded of course just like beautifier (script loader may be refactored/promisified). Minimized vendor code is okay at least in case of well-known libraries, also its parsing and compiling are usually noticeably faster. I'll review the code tomorrow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I always see an error in the console for any style, didn't investigate though.
lint.js:154 Uncaught TypeError: Cannot read property 'children' of null
at resizeLintReport (lint.js:154)
at renderLintReport (lint.js:147)
at update (lint.js:109)
at cm (lint.js:50)
_locales/bg/messages.json
Outdated
@@ -29,7 +29,7 @@ | |||
}, | |||
"issues": { | |||
"message": "Проблеми", | |||
"description": "Label for the CSSLint issues block on the style edit page" | |||
"description": "Label for the stylelint issues block on the style edit page" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one should be CSS linter
in all language files to mean both CSSLint and stylelint.
_locales/bg/messages.json
Outdated
@@ -665,8 +665,8 @@ | |||
"description": "Go to Options UI" | |||
}, | |||
"issuesHelp": { | |||
"message": "Проблеми, намерени от <a href='https://github.com/CSSLint/csslint' target='_blank'>CSSLint</a> при следните правила:", | |||
"description": "Help popup message for the CSSLint issues block on the style edit page" | |||
"message": "Проблеми, намерени от $link$ при следните правила:", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All messages with "placeholders"
object which you can copy from the English locale file by running tools/pull_locales_postprocess.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
_locales/en/messages.json
Outdated
}, | ||
"issuesHelp": { | ||
"message": "The issues found by <a href='https://github.com/CSSLint/csslint' target='_blank'>CSSLint</a> with these rules enabled:", | ||
"description": "Help popup message for the CSSLint issues block on the style edit page" | ||
"message": "The issues found by $link$ with these rules enabled:", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We had a bug in localization.js::tHTML() - the top-level text nodes were skipped, I've pushed a fix in master: 21b2ba5
_locales/bg/messages.json
Outdated
"message": "Проблеми, намерени от <a href='https://github.com/CSSLint/csslint' target='_blank'>CSSLint</a> при следните правила:", | ||
"description": "Help popup message for the CSSLint issues block on the style edit page" | ||
"message": "Проблеми, намерени от $link$ при следните правила:", | ||
"description": "Help popup message for the selected linter issues block on the style edit page" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
selected CSS linter
in all files to be consistent with "issues"
message
edit.html
Outdated
@@ -33,10 +34,15 @@ | |||
|
|||
<script src="vendor/codemirror/addon/edit/matchbrackets.js"></script> | |||
|
|||
<link rel="stylesheet" href="vendor/codemirror/addon/lint/lint.css" /> | |||
<!-- CSSLint --> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, linter script and stylesheets should only load when selected in the UI or at the start in edit.js if corresponding prefs.get('editor.linter')
is selected. Ditto for csslint. You can use some well-known script loader but only if it's really tiny or write your own or rework/adapt mine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The stylesheet is part of CodeMirror's linting tooltips. I would think that should be loaded no matter which linter is selected. Also, since CSSLint is the default and small, should that be loaded by default? Or do you want it to be dynamically loaded?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, you can add a third option "none" to the linters selector. It would be internally represented as an empty string in prefs
and <option value="" i18n-text="genericNoneLabel">
in html. And genericNoneLabel in _locales/en/messages.json.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if I used the "genericDisabledLabel" like that used in the Highlight dropdown?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And should "None" be the default? Or keep it on CSSLint?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- genericDisabledLabel is okay, I forgot about it.
- ideally, stylelint should be the default, but it's too soon to make it so, we and other users need to test it, you may be able to reduce the bundle etc.
- so, practically, we should preserve the historical behavior: keep csslint
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
edit/lint.js
Outdated
const link = '<a target="_blank" href="https://stylelint.io/demo/">Stylelint</a>'; | ||
const text = JSON.stringify({rules: rules}, null, 2); | ||
const content = `<textarea class="contents settings">${text}</textarea> | ||
<p>${t('setStylelintLink', link)}</p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We somewhat decided to use $element
to construct DOM in new code we write due to AMO nitpicking on innerHTML. You can look for examples in the existing code, it's pretty flexible for a 20-line function.
The same applies to other places except usages of t()
with localizable html.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will $element()
replace tHTML()
then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eventually we'll replace all tHTML usage along with the function itself. Meanwhile we use it only for translated messages, and $element for the new DOM-building code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
edit/lint.js
Outdated
} | ||
}, 3000); | ||
} | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed in this case AFAICT. Also, better to preventDefault() explicitly if that's what you want instead of return false
which was popular in the old days of js.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
edit/lint.js
Outdated
if (prefs.get('editor.linter') === 'stylelint') { | ||
updateLinter('stylelint'); | ||
} | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same.
@@ -0,0 +1,102 @@ | |||
// CodeMirror, copyright (c) by Marijn Haverbeke and others |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Er, css-lint.js
is the original name of this CodeMirror addon so it should remain the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
rules: { | ||
// ** recommended rules ** | ||
// ref: https://github.com/stylelint/stylelint-config-recommended/blob/master/index.js | ||
'at-rule-no-unknown': [ true, { 'severity': 'warning' }], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
The extra spaces after/before brackets aren't needed: we all use IDE with syntax highlight, not a plain text notepad. While these embellishments seem trendy and hip the existing code doesn't use this style.
-
The quotes around
severity
aren't needed as well and only add visual clutter. Actually I would probably extract it to a variable:const stylelintDefaultConfig = (defaultSeverity => ({ syntax: 'sugarss', rules: { 'at-rule-no-unknown': [true, defaultSeverity], 'block-no-empty': [true, defaultSeverity], ////////////////// }, }))({severity: 'warning'});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
I'll get to the rest of the changes when I get more time later today. |
@tophf Here is my attempt at using rollup to bundle stylelint... the readme includes details on why I haven't got it working yet. |
|
Ah, and please rebase on current master branch, then reupload the PR via |
And remove the unminified bundle, we'll risk it. |
All done except for one remaining issue... When the stylelint settings panel opens it used to look like it was working because the cm.setOption('mode', 'application/json');
cm.setOption('lint', 'json'); Can you tell if I'm missing something? |
@Mottie, I've reworked the config-related things myself as it was too complicated to explain. And changed a few other trivial things. Turns out you've used |
I think you're actually supposed to set the CodeMirror option to I'm glad it's finally merged! 🎉! |
It's supposed to be |
BTW, an easy instruction or a build script will be required on AMO to produce an exact copy of our minified bundle. |
I included a markdown file linking to the repo... We'll need to update it again since v8.1.0 will be released soon. |
I know, but I don't see an easy instruction or a build script. I meant something that @schomery can include in a note when submitting to AMO. |
I know, but I'm afraid the AMO drones won't be able to follow that. They also don't have time. When I say an easy instruction I mean something that's really easy. |
A build script that performs all modifications would be ideal. |
Ok, I'll see what I can do. |
1.1.4.1 is listed on AMO so apparently they've managed to follow your instructions. |
Nice! Hmm, too bad the Chrome version still hasn't been approved 😞 |
As mentioned in #149, the stylelint bundle file is about 3.25 Mb in size. I'm not sure if that makes this a reasonable change, but I went ahead and did it.
If this PR is accepted, all the locale files will need to be updated in transifex to remove reference to CSSLint.