Skip to content

Commit

Permalink
Enforce a minimal set of CSS selector complexity rules (#14238)
Browse files Browse the repository at this point in the history
* Disallow more than one bare HTML tag

* Remove dangling tab-manager references

these should have been removed in #8886

* Remove dialog button rule with complex selector which has no effect

* Remove stray style which should have been removed with #6653

* Remove one more dangling tab-manager style

* Enable `selector-max-class` stylelint rule

* Enable `selector-max-compound-selectors` stylelint rule

* Enable selector-max-universal: 1 to prevent very bad CSS

(while still allowing somewhat bad CSS for now).

* Make use of `stylelint-disable-next-line` where practical
  • Loading branch information
krassowski committed Mar 31, 2023
1 parent eca5b1d commit a4aa5eb
Show file tree
Hide file tree
Showing 24 changed files with 68 additions and 130 deletions.
11 changes: 11 additions & 0 deletions .stylelintrc.yaml
Expand Up @@ -30,3 +30,14 @@ rules:
selector-pseudo-class-no-unknown: null
selector-pseudo-element-no-unknown: null
selector-not-notation: null
# disallow use of more than one bare HTML tag like `div span` to avoid performance regression,
# while allowing compounded HTML tags like `button.jp-Button`
selector-max-type:
- 1
- ignore: "compounded"
# matching complex selectors is expensive
selector-max-class: 4
# TODO: decrease max-compound to 3
selector-max-compound-selectors: 4
# TODO: decrease to 0
selector-max-universal: 1
2 changes: 2 additions & 0 deletions docs/source/_static/css/custom.css
Expand Up @@ -3,6 +3,8 @@
* Distributed under the terms of the Modified BSD License.
*/

/* stylelint-disable selector-max-type */

/* Navbar at the top */
.jupyter-nav-logo {
padding: 0;
Expand Down
1 change: 0 additions & 1 deletion galata/src/galata.ts
Expand Up @@ -62,7 +62,6 @@ export namespace galata {
export type DefaultSidebarTabId =
| 'filebrowser'
| 'jp-running-sessions'
| 'tab-manager'
| 'jp-property-inspector'
| 'table-of-contents'
| 'extensionmanager.main-view'
Expand Down
1 change: 1 addition & 0 deletions packages/application/style/menus.css
Expand Up @@ -69,6 +69,7 @@
box-shadow: var(--jp-elevation-z6);
}

/* stylelint-disable-next-line selector-max-class */
.jp-LabShell[data-shell-mode='single-document']
.lm-MenuBar.lm-mod-active
.lm-MenuBar-item.lm-mod-active {
Expand Down
4 changes: 4 additions & 0 deletions packages/application/style/sidepanel.css
Expand Up @@ -100,6 +100,8 @@

/* Borders */

/* stylelint-disable selector-max-class */

.jp-SideBar.lm-TabBar .lm-TabBar-tab + .lm-TabBar-tab {
border-top: var(--jp-border-width) solid var(--jp-layout-color2);
}
Expand Down Expand Up @@ -189,6 +191,8 @@
border-right: var(--jp-border-width) solid var(--jp-border-color1);
}

/* stylelint-enable selector-max-class */

/* Stack panels */

#jp-left-stack > .lm-Widget,
Expand Down
4 changes: 4 additions & 0 deletions packages/application/style/tabs.css
Expand Up @@ -129,6 +129,8 @@
margin-top: 0;
}

/* stylelint-disable selector-max-class */

.lm-DockPanel-tabBar .lm-TabBar.lm-mod-left .lm-TabBar-tab.lm-mod-current,
.lm-DockPanel-tabBar .lm-TabBar.lm-mod-right .lm-TabBar-tab.lm-mod-current {
min-width: 80px;
Expand All @@ -149,6 +151,8 @@
margin-right: 4px;
}

/* stylelint-enable selector-max-class */

.lm-TabBar-tab.lm-mod-drag-image {
background: var(--jp-layout-color1);
color: var(--jp-ui-font-color1);
Expand Down
5 changes: 4 additions & 1 deletion packages/debugger/src/panels/sources/sourcepath.tsx
Expand Up @@ -19,7 +19,10 @@ export const SourcePathComponent = ({
return (
<UseSignal signal={model.currentSourceChanged} initialSender={model}>
{(model): JSX.Element => (
<span onClick={(): void => model?.open()}>
<span
onClick={(): void => model?.open()}
className="jp-DebuggerSources-header-path"
>
{model?.currentSource?.path ?? ''}
</span>
)}
Expand Down
4 changes: 2 additions & 2 deletions packages/debugger/style/callstack.css
Expand Up @@ -23,12 +23,12 @@
font-size: var(--jp-ui-font-size1);
}

.jp-DebuggerCallstack-body ul li {
.jp-DebuggerCallstack-body li {
padding: 5px;
padding-left: 8px;
}

.jp-DebuggerCallstack-body ul li.selected {
.jp-DebuggerCallstack-body li.selected {
color: white;
background: var(--jp-brand-color1);
}
Expand Down
9 changes: 0 additions & 9 deletions packages/debugger/style/kernelSources.css
Expand Up @@ -22,15 +22,6 @@
overflow-y: auto;
}

.jp-DebuggerKernelSources-header > div > span {
overflow: hidden;
cursor: pointer;
text-overflow: ellipsis;
white-space: nowrap;
font-size: var(--jp-ui-font-size0);
color: var(--jp-ui-font-color1);
}

.jp-DebuggerKernelSource-filterBox {
padding: 0;
flex: 0 0 auto;
Expand Down
2 changes: 1 addition & 1 deletion packages/debugger/style/sources.css
Expand Up @@ -21,7 +21,7 @@
height: 100%;
}

.jp-DebuggerSources-header > div > span {
.jp-DebuggerSources-header-path {
overflow: hidden;
cursor: pointer;
text-overflow: ellipsis;
Expand Down
3 changes: 1 addition & 2 deletions packages/extensionmanager/src/widget.tsx
Expand Up @@ -257,15 +257,14 @@ function ListView(props: ListView.IProperties): React.ReactElement<any> {
previousLabel={'<'}
nextLabel={'>'}
breakLabel="..."
breakClassName={'break-me'}
breakClassName={'break'}
initialPage={(props.initialPage ?? 1) - 1}
pageCount={props.numPages}
marginPagesDisplayed={2}
pageRangeDisplayed={3}
onPageChange={(data: { selected: number }) =>
props.onPage(data.selected + 1)
}
containerClassName={'pagination'}
activeClassName={'active'}
/>
</div>
Expand Down
16 changes: 9 additions & 7 deletions packages/extensionmanager/style/base.css
Expand Up @@ -105,25 +105,27 @@
padding-right: 0;
}

.jp-extensionmanager-view .pagination li {
.jp-extensionmanager-pagination li {
display: inline-block;
}

.jp-extensionmanager-view .pagination li a {
/* stylelint-disable selector-max-type */
.jp-extensionmanager-pagination li > a {
padding: 0 5px;
cursor: pointer;
}
/* stylelint-enable selector-max-type */

.jp-extensionmanager-view .pagination li.active a {
.jp-extensionmanager-pagination li.active > a {
background: var(--jp-brand-color1);
color: #fff;
color: var(--jp-layout-color1);
}

.jp-extensionmanager-view .pagination li a:hover {
.jp-extensionmanager-pagination li > a:hover {
background-color: var(--jp-layout-color2);
color: unset;
}

.jp-extensionmanager-view .pagination .break a {
.jp-extensionmanager-pagination .break > a {
cursor: default;
}

Expand Down
10 changes: 8 additions & 2 deletions packages/help-extension/src/licenses.tsx
Expand Up @@ -17,6 +17,8 @@ import { h, VirtualElement } from '@lumino/virtualdom';
import { Panel, SplitPanel, TabBar, Widget } from '@lumino/widgets';
import * as React from 'react';

const FILTER_SECTION_TITLE_CLASS = 'jp-Licenses-Filters-title';

/**
* A license viewer
*/
Expand Down Expand Up @@ -511,7 +513,9 @@ export namespace Licenses {
return (
<div>
<label>
<strong>{trans.__('Filter Licenses By')}</strong>
<strong className={FILTER_SECTION_TITLE_CLASS}>
{trans.__('Filter Licenses By')}
</strong>
</label>
<ul>
<li>
Expand All @@ -528,7 +532,9 @@ export namespace Licenses {
</li>
</ul>
<label>
<strong>{trans.__('Distributions')}</strong>
<strong className={FILTER_SECTION_TITLE_CLASS}>
{trans.__('Distributions')}
</strong>
</label>
</div>
);
Expand Down
13 changes: 3 additions & 10 deletions packages/help-extension/style/base.css
Expand Up @@ -40,13 +40,6 @@
line-height: 1.12;
}

.jp-Dialog
.jp-Dialog-content
.jp-Dialog-footer
.jp-Dialog-button.jp-About-button {
margin-right: 0;
}

.jp-About-version {
display: block;
padding-top: 8px;
Expand Down Expand Up @@ -114,7 +107,7 @@
display: block;
}

.jp-Licenses-Filters label strong {
.jp-Licenses-Filters-title {
font-weight: 600;
text-transform: uppercase;
letter-spacing: 1px;
Expand Down Expand Up @@ -209,7 +202,7 @@
text-align: left;
}

.jp-Licenses-Grid table td:nth-child(1) {
.jp-Licenses-Grid td:nth-child(1) {
max-width: calc(2 * var(--jp-ui-font-size1));
}

Expand All @@ -221,7 +214,7 @@
background-color: transparent;
}

.jp-Licenses-Grid table tr.jp-mod-selected {
.jp-Licenses-Grid tr.jp-mod-selected {
background-color: var(--jp-brand-color1);
color: #fff;
}
Expand Down
5 changes: 2 additions & 3 deletions packages/logconsole-extension/style/base.css
Expand Up @@ -26,10 +26,9 @@
background-color: var(--jp-brand-color1);
}

/* Need to be very specific to override the typestyle styles on status bar components */
/* Override semi-transparent white with opaque white for higher contrast */
.jp-LogConsoleStatusItem.jp-mod-selected,
.jp-LogConsoleStatusItem.jp-mod-selected div,
.jp-LogConsoleStatusItem.jp-mod-selected div span {
.jp-LogConsoleStatusItem.jp-mod-selected .jp-StatusBar-TextItem {
color: white;
}

Expand Down
2 changes: 2 additions & 0 deletions packages/notebook/style/base.css
Expand Up @@ -28,6 +28,8 @@
| Notebook
|----------------------------------------------------------------------------*/

/* stylelint-disable selector-max-class */

.jp-NotebookPanel {
display: block;
height: 100%;
Expand Down
4 changes: 4 additions & 0 deletions packages/rendermime/style/base.css
Expand Up @@ -329,6 +329,8 @@

/* Lists */

/* stylelint-disable selector-max-type, selector-max-compound-selectors */

.jp-RenderedHTMLCommon ul:not(.list-inline),
.jp-RenderedHTMLCommon ol:not(.list-inline) {
padding-left: 2em;
Expand Down Expand Up @@ -378,6 +380,8 @@
margin-bottom: 0;
}

/* stylelint-enable selector-max-type, selector-max-compound-selectors */

.jp-RenderedHTMLCommon hr {
color: var(--jp-border-color2);
background-color: var(--jp-border-color1);
Expand Down
30 changes: 0 additions & 30 deletions packages/settingeditor/style/base.css
Expand Up @@ -125,19 +125,6 @@
background-color: var(--jp-error-color0);
}

.jp-PluginList button.jp-mod-selected.jp-ErrorPlugin span {
color: var(--jp-error-color0);
}

.jp-PluginList button.jp-mod-selected span {
font-weight: var(--jp-content-heading-font-weight);
color: var(--jp-brand-color1);
}

.jp-FormComponent li span {
overflow: hidden;
}

.jp-SettingEditor-header {
font-size: var(--jp-content-font-size4);
font-weight: var(--jp-content-heading-font-weight);
Expand All @@ -150,10 +137,6 @@
background-color: var(--jp-layout-color0);
}

ul.jp-PluginList li.jp-mod-selected span.jp-PluginList-icon.jp-FileIcon {
background-image: var(--jp-icon-file-selected);
}

.jp-PluginList-icon {
display: flex;
height: 20px;
Expand All @@ -178,19 +161,6 @@ ul.jp-PluginList li.jp-mod-selected span.jp-PluginList-icon.jp-FileIcon {
align-items: center;
}

.jp-ToolbarButtonComponent-label
.jp-SettingsRawEditor.jp-mod-error
.jp-Toolbar-item.jp-BugIcon::after {
color: red;
content: '\25CF'; /* Unicode circle character (error dot) */
font-size: 7px;
width: 100%;
height: 100%;
position: absolute;
top: 4px;
left: 6px;
}

.jp-SettingsRawEditor .jp-Inspector {
border-top: 2px solid var(--jp-layout-color2);
min-height: var(--jp-private-settingeditor-debug-height);
Expand Down
1 change: 1 addition & 0 deletions packages/toc/style/base.css
Expand Up @@ -45,6 +45,7 @@
list-style-type: none;
}

/* stylelint-disable-next-line selector-max-type */
.jp-TableOfContents li > ol {
/* Align left border with triangle icon center */
padding-left: 11px;
Expand Down
8 changes: 0 additions & 8 deletions packages/ui-components/src/style/icon.ts
Expand Up @@ -264,10 +264,6 @@ export namespace LabIconStyle {
$nest: {
'.lm-DockPanel-tabBar &': {
marginRight: '4px'
},
'#tab-manager &': {
marginRight: '2px',
position: 'relative'
}
}
},
Expand All @@ -276,10 +272,6 @@ export namespace LabIconStyle {
'.lm-DockPanel-tabBar &': {
height: '14px',
width: '14px'
},
'#tab-manager &': {
height: '16px',
width: '16px'
}
}
},
Expand Down
1 change: 1 addition & 0 deletions packages/ui-components/style/base.css
Expand Up @@ -179,6 +179,7 @@ input::placeholder {
}

/* Use our own theme for hover and option styles */
/* stylelint-disable-next-line selector-max-type */
.jp-HTMLSelect.jp-DefaultStyle select:hover,
.jp-HTMLSelect.jp-DefaultStyle select > option {
background-color: var(--jp-layout-color2);
Expand Down

0 comments on commit a4aa5eb

Please sign in to comment.