| 98 |
98 |
|
echo " Lower INLINE_HANDLER_BUDGET in scripts/lint-frontend.sh to $inline_count to lock in the gain."
|
| 99 |
99 |
|
fi
|
| 100 |
100 |
|
|
|
101 |
+ |
# 10. A described member stays in flow.
|
|
102 |
+ |
# Rule 1 of wiki `layout-room-and-fallback`: every member of a described
|
|
103 |
+ |
# group is in flow, and layering is the closed layer set rather than a
|
|
104 |
+ |
# member positioning itself. `position: absolute` is the one construction
|
|
105 |
+ |
# the description layer cannot audit -- it takes the member out of flow, so
|
|
106 |
+ |
# it contributes no width to the row it shares, nothing can collide with it,
|
|
107 |
+ |
# and therefore nothing prevents the collision. That was live in this file
|
|
108 |
+ |
# for months (`.tab-group > .subview > .page-header`, removed 5fa511a) and
|
|
109 |
+ |
# cost the toolbar-over-pills overlap at 700 and 600.
|
|
110 |
+ |
#
|
|
111 |
+ |
# Scope: only a selector whose LAST compound names a described member, so
|
|
112 |
+ |
# `.page-header .some-child { position: absolute }` is the child's business
|
|
113 |
+ |
# and is not flagged. Pseudo-elements are decoration, not members, and are
|
|
114 |
+ |
# skipped. The app owns plenty of legitimate layering -- modals, the scrim,
|
|
115 |
+ |
# `.track-entry` -- and none of it wears these class names; anything that
|
|
116 |
+ |
# needs to may be added to ALLOW below WITH A REASON.
|
|
117 |
+ |
DESCRIBED_MEMBERS='run|page-header|subview-head|pill-nav'
|
|
118 |
+ |
hits=$(awk -v members="$DESCRIBED_MEMBERS" '
|
|
119 |
+ |
# Allow-list: exact selector text, each with the reason it is layered.
|
|
120 |
+ |
# (empty today -- add as `ALLOW[".selector"] = "why"`)
|
|
121 |
+ |
BEGIN { split("", ALLOW) }
|
|
122 |
+ |
/\{/ { sel = $0; sub(/\{.*/, "", sel); gsub(/^[ \t]+|[ \t]+$/, "", sel); if (sel != "") current = sel; next }
|
|
123 |
+ |
/position:[ \t]*(absolute|fixed)/ {
|
|
124 |
+ |
if (current == "") next
|
|
125 |
+ |
n = split(current, parts, ",")
|
|
126 |
+ |
for (i = 1; i <= n; i++) {
|
|
127 |
+ |
one = parts[i]
|
|
128 |
+ |
gsub(/^[ \t]+|[ \t]+$/, "", one)
|
|
129 |
+ |
if (one in ALLOW) continue
|
|
130 |
+ |
if (one ~ /::(before|after)/) continue
|
|
131 |
+ |
last = one
|
|
132 |
+ |
sub(/.*[ >+~]/, "", last)
|
|
133 |
+ |
if (last ~ ("\\.(" members ")")) printf "%s:%d: %s { %s }\n", FILENAME, NR, one, $0
|
|
134 |
+ |
}
|
|
135 |
+ |
}
|
|
136 |
+ |
' "$SRC_CSS" | sed 's/[ \t]\+/ /g' || true)
|
|
137 |
+ |
report "described-members-in-flow" "A described member takes itself out of flow. Give the group a Fallback instead, or add the selector to ALLOW in this rule with its reason." "$hits"
|
|
138 |
+ |
|
| 101 |
139 |
|
if [ $violations -eq 0 ]; then
|
| 102 |
140 |
|
echo "frontend lint: clean"
|
| 103 |
141 |
|
exit 0
|