Skip to content

Commit 11f116b

Browse files
committed
Show at-rules and related refactor
1 parent e94eaef commit 11f116b

File tree

8 files changed

+132
-29
lines changed

8 files changed

+132
-29
lines changed

src/syntax/prepare.js

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const functionSyntaxes = new WeakMap();
55
const { definitionSyntax } = csstree;
66

77
function syntaxName(syntax) {
8-
const { type, name } = syntax || {};
8+
const { type, name, parent } = syntax || {};
99

1010
switch (type) {
1111
case 'Property':
@@ -17,6 +17,15 @@ function syntaxName(syntax) {
1717
case 'Function':
1818
return name + '()';
1919

20+
case 'Atrule':
21+
return '@' + name;
22+
23+
case 'AtrulePrelude':
24+
return '@' + name + ':prelude';
25+
26+
case 'AtruleDescriptor':
27+
return '@' + parent + '/' + name;
28+
2029
default:
2130
return name;
2231
}
@@ -133,7 +142,14 @@ function collectUsage(type, dict, defaultSyntax) {
133142
visited[type + ':' + name] = true;
134143
host = dict[name];
135144
hostStack.push(host);
136-
processDescriptor(host);
145+
if (type === 'Atrule') {
146+
processDescriptor(host.prelude);
147+
for (let descriptor in host.discriptors) {
148+
processDescriptor(host.descriptors[descriptor]);
149+
}
150+
} else {
151+
processDescriptor(host);
152+
}
137153
hostStack.pop();
138154
}
139155
}
@@ -185,10 +201,25 @@ function syntaxRefs(syntax, typeDict, globalDict) {
185201
}
186202

187203
discovery.setPrepare(function(data, { defineObjectMarker, addQueryHelpers }) {
188-
const { properties, types } = csstree.lexer;
204+
const { properties, types, atrules } = csstree.lexer;
189205
const functions = Object.create(null);
190-
const typeOrder = ['Property', 'Type', 'Function'];
206+
const typeOrder = ['Atrule', 'AtrulePrelude', 'AtruleDescriptor', 'Property', 'Type', 'Function'];
191207
const typeDict = {
208+
Atrule: atrules,
209+
AtrulePrelude: Object.fromEntries(
210+
Object.entries(atrules)
211+
.map(([key, { prelude }]) => prelude && [key, prelude])
212+
.filter(Boolean)
213+
),
214+
AtruleDescriptor: Object.fromEntries(
215+
Object.entries(atrules).reduce(
216+
(res, [key, { descriptors }]) =>
217+
descriptors
218+
? res.concat(Object.entries(descriptors).map(([name, value]) => [key + '/' + name, value]))
219+
: res,
220+
[]
221+
)
222+
),
192223
Property: properties,
193224
Type: types,
194225
Function: functions
@@ -206,19 +237,15 @@ discovery.setPrepare(function(data, { defineObjectMarker, addQueryHelpers }) {
206237

207238
csstree.lexer.validate();
208239
csstree.lexer.functions = functions;
240+
collectUsage('Atrule', atrules, csstree.lexer);
209241
collectUsage('Property', properties, csstree.lexer);
210242
collectUsage('Type', types, csstree.lexer);
211243

212-
data.dict = [
213-
...Object.values(properties),
214-
...Object.values(types),
215-
...Object.values(functions)
216-
];
217-
218-
data.dict.forEach(item => {
244+
data.dict = [].concat(...Object.values(typeDict).map(dict => Object.values(dict)));
245+
for (const item of data.dict) {
219246
item.refs = syntaxRefs(item.syntax, typeDict, data.dict);
220247
markers[item.type](item);
221-
});
248+
}
222249

223250
addQueryHelpers({
224251
formatName: syntaxName,
@@ -227,10 +254,22 @@ discovery.setPrepare(function(data, { defineObjectMarker, addQueryHelpers }) {
227254

228255
return idx !== -1 ? idx : Infinity;
229256
},
257+
isProblem: discovery.queryFn('(no match and type != "Atrule") or refs.resolved.[no match]'),
230258
mdn(current) {
231259
if (current) {
232-
if (current.type === 'Property' || current.type === 'Type') {
233-
return data.mdn[current.type === 'Property' ? 'properties' : 'syntaxes'][current.name] || null;
260+
switch (current.type) {
261+
case 'Atrule':
262+
case 'AtrulePrelude':
263+
return data.mdn.atRules['@' + current.name] || null;
264+
265+
case 'AtruleDescriptor': {
266+
const atrule = data.mdn.atRules['@' + current.parent];
267+
return (atrule && atrule.descriptors && atrule.descriptors[current.name]) || null;
268+
}
269+
270+
case 'Property':
271+
case 'Type':
272+
return data.mdn[current.type === 'Property' ? 'properties' : 'syntaxes'][current.name] || null;
234273
}
235274
}
236275
return null;

src/syntax/ui/page/default.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ discovery.page.define('default', [
2121
{ title: 'Properties', query: 'dict.[type="Property"]' },
2222
{ title: 'Types', query: 'dict.[type="Type"]' },
2323
{ title: 'Functions', query: 'dict.[type="Function"]' },
24-
{ title: 'Problems', query: 'dict.[no match or refs.resolved.[no match]]', href: '#problems' }
24+
{ title: 'Problems', query: 'dict.[isProblem()]', href: '#problems' }
2525
],
2626
content: {
2727
view: 'inline-list',

src/syntax/ui/page/problems.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,14 @@ discovery.page.define('problems', [
1010
emptyText: 'No problems',
1111
data: `
1212
dict
13-
.[no match or refs.resolved.[no match]]
14-
.[no #.type or type=#.type]
15-
.sort(<[match?1:0, type.typeSorting(), name]>)
13+
.[isProblem()]
14+
.sort(match desc, type.typeSorting() asc, name asc)
1615
`,
1716
itemConfig: {
1817
className: data => !data.match ? 'missed' : ''
1918
},
2019
item: [
21-
'auto-link',
20+
'auto-link{ fallback: "text:formatName()" }',
2221
'text:" = "',
2322
{
2423
view: 'switch',

src/syntax/ui/page/syntax-page.css

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
.page-Atrule .view-alert-danger,
2+
.page-AtrulePrelude .view-alert-danger,
3+
.page-AtruleDescriptor .view-alert-danger,
14
.page-Property .view-alert-danger,
25
.page-Type .view-alert-danger,
36
.page-Function .view-alert-danger {
@@ -6,6 +9,9 @@
69
white-space: pre-wrap;
710
}
811

12+
.page-Atrule > *,
13+
.page-AtrulePrelude > *,
14+
.page-AtruleDescriptor > *,
915
.page-Property > *,
1016
.page-Type > *,
1117
.page-Function > * {
@@ -34,6 +40,9 @@
3440
display: block;
3541
}
3642

43+
.page-Atrule .view-header .view-badge,
44+
.page-AtrulePrelude .view-header .view-badge,
45+
.page-AtruleDescriptor .view-header .view-badge,
3746
.page-Property .view-header .view-badge,
3847
.page-Type .view-header .view-badge,
3948
.page-Function .view-header .view-badge {
@@ -70,3 +79,6 @@
7079
.syntax-section .view-tab.active {
7180
padding-bottom: 5px;
7281
}
82+
.descriptor-table td:first-child {
83+
white-space: nowrap;
84+
}

src/syntax/ui/page/syntax-page.js

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
const page = {
44
view: 'context',
5-
data: 'dict.pick(<type=#.page and name=#.id>)',
5+
data: 'dict[=>type=#.page and name=#.id]',
66
content: [
77
{
88
view: 'page-header',
@@ -11,7 +11,7 @@ const page = {
1111
},
1212
{
1313
view: 'alert-danger',
14-
when: 'no match',
14+
when: 'no match and type != "Atrule"',
1515
content: 'text:"Syntax definition is missed"'
1616
},
1717
'syntax-test',
@@ -85,19 +85,53 @@ const page = {
8585
}
8686
]
8787
},
88+
{
89+
view: 'context',
90+
when: 'type = "Atrule"',
91+
content: [
92+
{
93+
view: 'context',
94+
when: 'prelude',
95+
content: [
96+
'h3:"Prelude"',
97+
'syntax:prelude'
98+
]
99+
},
100+
{
101+
view: 'context',
102+
when: 'descriptors',
103+
content: [
104+
'h3:"Descriptors"',
105+
{
106+
view: 'table',
107+
className: 'descriptor-table',
108+
data: 'descriptors.values()',
109+
cols: [
110+
{ header: 'Name', content: ['auto-link{ content: "text:entity.name" }'] },
111+
{ header: 'Syntax', content: 'syntax' }
112+
]
113+
}
114+
]
115+
}
116+
]
117+
},
88118
{
89119
view: 'match-graph',
90120
when: 'match',
91121
data: 'match'
92122
},
93123
{
94124
view: 'section',
125+
when: 'not type ~= /^Atrule/',
95126
header: 'text:"Used by"',
96127
content: 'used-by'
97128
}
98129
]
99130
};
100131

132+
discovery.page.define('Atrule', page);
133+
discovery.page.define('AtruleDescriptor', page);
134+
discovery.page.define('AtrulePrelude', page);
101135
discovery.page.define('Property', page);
102136
discovery.page.define('Type', page);
103137
discovery.page.define('Function', page);

src/syntax/ui/sidebar.css

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22
width: 300px;
33
}
44

5+
.discovery-sidebar .nested {
6+
padding-left: 20px;
7+
}
8+
59
.discovery-sidebar .variants {
610
color: #888;
711
}
812

9-
.discovery-sidebar .missed {
10-
color: #a00;
13+
.discovery-sidebar .missed .view-link:first-child {
14+
color: #d00;
1115
text-decoration-color: #a008;
1216
}
1317

src/syntax/ui/sidebar.js

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,22 @@ discovery.view.define('sidebar', {
55
content: {
66
view: 'list',
77
data: `
8-
dict.[no #.filter or name~=#.filter]
8+
dict.[
9+
type not in ["AtrulePrelude", "AtruleDescriptor"]
10+
and (name~=#.filter or descriptors.values().name~=#.filter)
11+
]
912
.group(=>type)
1013
.(
1114
// prepare items
1215
$items: value.({
1316
type,
1417
name,
18+
parent,
19+
nested: type = "Atrule" ? descriptors.values() : null,
1520
syntax,
16-
missed: no match ,
17-
brokenRefs: refs.resolved.[no match]
21+
missed: no match and type != 'Atrule',
22+
brokenRefs: (type != "Atrule" ? $ : (descriptors.values() or []) + (prelude or []))
23+
.refs.resolved.[no match]
1824
}).sort(=>name);
1925
2026
// section info
@@ -44,10 +50,12 @@ discovery.view.define('sidebar', {
4450
content: {
4551
view: 'list',
4652
data: 'items',
53+
itemConfig: {
54+
className: data => data.missed ? 'missed' : ''
55+
},
4756
item: [
4857
{
4958
view: 'auto-link',
50-
className: data => data.missed ? 'missed' : '',
5159
content: 'text-match:{ text, match: #.filter }'
5260
},
5361
{
@@ -64,14 +72,22 @@ discovery.view.define('sidebar', {
6472
{
6573
view: 'badge',
6674
className: 'patched-badge',
67-
when: 'type != "Function" and no mdn()',
75+
when: 'type != "Function" and no mdn() and no missed',
6876
data: '{ text: "added" }'
6977
},
7078
{
7179
view: 'pill-badge',
7280
className: 'danger-badge',
7381
when: 'brokenRefs',
7482
data: '{ text: brokenRefs.size() }'
83+
},
84+
{
85+
view: 'list',
86+
className: 'nested',
87+
when: '#.filter',
88+
data: 'nested.[name~=#.filter]',
89+
whenData: true,
90+
item: 'auto-link{ content: "text-match:{ text: entity.name, match: #.filter }" }'
7591
}
7692
]
7793
}

src/syntax/ui/view/syntax.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ function markupSyntax(syntax, match) {
1414
const error = !entityDescriptor || !entityDescriptor.object.match;
1515

1616
str = `<a href="#${node.type}:${node.name}"${error ? ' class="error"' : ''}>${escapeHtml(str)}</a>`;
17-
1817
}
1918

2019
if (match && match.type === node.type && match.name === node.name) {

0 commit comments

Comments
 (0)