Hold'em: every seat on the ring is the same seat, and the ring is measured before it is believed #122
@@ -549,8 +549,12 @@
|
|||||||
|
|
||||||
<div id="rulingsOverlay" hidden>
|
<div id="rulingsOverlay" hidden>
|
||||||
<div id="rulingsSheet" role="dialog" aria-labelledby="rulingsTitle">
|
<div id="rulingsSheet" role="dialog" aria-labelledby="rulingsTitle">
|
||||||
<div class="seatSheetGrip" aria-hidden="true"></div>
|
@* The grip belongs inside the header, not above it, because the header is stuck
|
||||||
|
to the top of the scrollport — anything above a sticky thing is something the
|
||||||
|
list scrolls out through. The seat menu's header is built the same way, and
|
||||||
|
for the same reason. *@
|
||||||
<div class="rulingsHeader">
|
<div class="rulingsHeader">
|
||||||
|
<div class="seatSheetGrip" aria-hidden="true"></div>
|
||||||
<h2 id="rulingsTitle" tabindex="-1" data-modal-focus>Common rulings</h2>
|
<h2 id="rulingsTitle" tabindex="-1" data-modal-focus>Common rulings</h2>
|
||||||
<button id="closeRulingsBtn" data-modal-close class="holdemBtn holdemBtnSmall holdemBtnGhost" type="button">Done</button>
|
<button id="closeRulingsBtn" data-modal-close class="holdemBtn holdemBtnSmall holdemBtnGhost" type="button">Done</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -579,6 +583,14 @@
|
|||||||
Not exclusive (no `name` attribute): closing one because another opened moves
|
Not exclusive (no `name` attribute): closing one because another opened moves
|
||||||
everything under the dealer's finger, which is the disorientation the
|
everything under the dealer's finger, which is the disorientation the
|
||||||
accordion is here to avoid. *@
|
accordion is here to avoid. *@
|
||||||
|
|
||||||
|
@* Six and six, down one column and then the next. Two boxes rather than one
|
||||||
|
list so that landscape can lay them side by side without the columns
|
||||||
|
sharing rows: opening a ruling in one of them moves what is under it in
|
||||||
|
that column and nothing else. Everywhere but landscape the wrappers are
|
||||||
|
`display: contents` and the twelve are one column, exactly as before. *@
|
||||||
|
<div class="rulingsList">
|
||||||
|
<div class="rulingsColumn">
|
||||||
<details class="ruling">
|
<details class="ruling">
|
||||||
<summary><h3>Redeal it — misdeal</h3></summary>
|
<summary><h3>Redeal it — misdeal</h3></summary>
|
||||||
<ul>
|
<ul>
|
||||||
@@ -654,7 +666,9 @@
|
|||||||
off the short one. The action bar follows this for you.
|
off the short one. The action bar follows this for you.
|
||||||
</p>
|
</p>
|
||||||
</details>
|
</details>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="rulingsColumn">
|
||||||
<details class="ruling">
|
<details class="ruling">
|
||||||
<summary><h3>Chips nobody called come back</h3></summary>
|
<summary><h3>Chips nobody called come back</h3></summary>
|
||||||
<p>
|
<p>
|
||||||
@@ -733,6 +747,8 @@
|
|||||||
decide how much to bet. Say it, or push it all at once.
|
decide how much to bet. Say it, or push it all at once.
|
||||||
</p>
|
</p>
|
||||||
</details>
|
</details>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<p class="rulingsSource">
|
<p class="rulingsSource">
|
||||||
Follows the Tournament Directors Association rules, which most rooms and
|
Follows the Tournament Directors Association rules, which most rooms and
|
||||||
|
|||||||
@@ -2179,29 +2179,60 @@ input[type="checkbox"] {
|
|||||||
max-width: 460px;
|
max-width: 460px;
|
||||||
max-height: 86vh;
|
max-height: 86vh;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
overscroll-behavior: contain;
|
||||||
background: linear-gradient(180deg, var(--surface-2), var(--surface-1));
|
background: linear-gradient(180deg, var(--surface-2), var(--surface-1));
|
||||||
border: 1px solid var(--line);
|
border: 1px solid var(--line);
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
border-radius: var(--r-lg) var(--r-lg) 0 0;
|
border-radius: var(--r-lg) var(--r-lg) 0 0;
|
||||||
padding: var(--sp-1) var(--sp-4) calc(var(--sp-5) + env(safe-area-inset-bottom, 0px));
|
/* No padding at the top: the header owns it, because the header is sticky and a
|
||||||
|
gap above a sticky thing is a gap the list scrolls through. The seat menu's
|
||||||
|
sheet is built the same way, one section down. */
|
||||||
|
padding: 0 var(--sp-4) calc(var(--sp-5) + env(safe-area-inset-bottom, 0px));
|
||||||
box-shadow: 0 -14px 40px rgba(0, 0, 0, 0.65);
|
box-shadow: 0 -14px 40px rgba(0, 0, 0, 0.65);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Stuck to the top of the sheet's own scrollport, for the reason the seat menu's header
|
||||||
|
is: the way out should not scroll away. This sheet is the longer of the two and never
|
||||||
|
had it. Measured before: on a 360x640 phone the twelve shut rulings are 791px of a
|
||||||
|
549px sheet, so at the bottom of that scroll Done sits 221px above the top edge — and
|
||||||
|
on a 390x844 phone with one ruling opened, which is the only reason anybody is in
|
||||||
|
here, 262px. A dealer who has read the answer has to scroll back past it to leave. */
|
||||||
.rulingsHeader {
|
.rulingsHeader {
|
||||||
display: flex;
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 1;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1fr) auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--sp-2);
|
column-gap: var(--sp-2);
|
||||||
margin-bottom: var(--sp-2);
|
/* Out to the sheet's edges and back again, so nothing shows through either side of
|
||||||
|
a header sitting over a scrolling list. */
|
||||||
|
margin: 0 calc(var(--sp-4) * -1) var(--sp-2);
|
||||||
|
padding: var(--sp-1) var(--sp-4) var(--sp-2);
|
||||||
|
background: var(--surface-2);
|
||||||
|
border-bottom: 1px solid var(--line);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The grip is inside the header now rather than above it — above a sticky element is
|
||||||
|
the one place on this sheet that scrolls out of sight. */
|
||||||
|
.rulingsHeader .seatSheetGrip {
|
||||||
|
grid-column: 1 / -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rulingsHeader h2 {
|
.rulingsHeader h2 {
|
||||||
flex: 1;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: var(--fs-lg);
|
font-size: var(--fs-lg);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: var(--text-bright);
|
color: var(--text-bright);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Two boxes of six that are not boxes at all: `display: contents` hands the twelve
|
||||||
|
rulings straight to the list, so every layout but landscape sees the single column it
|
||||||
|
always had. Landscape turns them back into boxes and stands them side by side. */
|
||||||
|
.rulingsColumn {
|
||||||
|
display: contents;
|
||||||
|
}
|
||||||
|
|
||||||
.rulingsIntro {
|
.rulingsIntro {
|
||||||
margin: 0 0 var(--sp-4);
|
margin: 0 0 var(--sp-4);
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
@@ -5853,6 +5884,116 @@ body.hasActionBar #toastHost {
|
|||||||
inset: max(24px, 12%) 44px min(26px, 12%);
|
inset: max(24px, 12%) 44px min(26px, 12%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---------- Common rulings: the sheet becomes the screen ----------
|
||||||
|
|
||||||
|
Everywhere else this is a bottom sheet a dealer scrolls, and that works because
|
||||||
|
upright there is height to scroll through. Sideways there is not. Measured at
|
||||||
|
844x390 before this: a 460px-wide sheet standing in the middle of an 844px window
|
||||||
|
with 384px of that window unused either side of it, 754px of rulings in 334px of
|
||||||
|
scrollport, 111px of it spent on a title and a caveat that stand still — four of
|
||||||
|
the twelve names on screen, and the dealer is looking one up with an argument
|
||||||
|
going on at the table.
|
||||||
|
|
||||||
|
So the sheet takes the window, and the width pays for the height. Material's rule
|
||||||
|
for a bottom sheet on a landscape screen is to stop being one — a side sheet on a
|
||||||
|
wide screen, a full-screen dialog when the content needs real scrolling — and this
|
||||||
|
is the tool's own move as well: the action bar becomes a right-hand rail under
|
||||||
|
exactly this query, for exactly this reason.
|
||||||
|
|
||||||
|
The twelve go into two columns of six. Measured after: all twelve names on screen
|
||||||
|
at 844x390 with nothing to scroll at all, and the columns are 400px wide, which is
|
||||||
|
a better measure for the prose inside an open ruling than the 460 it had.
|
||||||
|
|
||||||
|
Capped rather than unbounded, because this query also matches a short desktop
|
||||||
|
window, and two columns of a 1400px window would be 680px lines of body text. */
|
||||||
|
#rulingsOverlay {
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
#rulingsSheet {
|
||||||
|
max-width: 62rem;
|
||||||
|
max-height: none;
|
||||||
|
height: 100%;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
/* The list inside does the scrolling now, so the sheet itself does none. */
|
||||||
|
overflow: hidden;
|
||||||
|
padding:
|
||||||
|
var(--sp-2)
|
||||||
|
calc(var(--sp-4) + env(safe-area-inset-right, 0px))
|
||||||
|
calc(var(--sp-2) + env(safe-area-inset-bottom, 0px))
|
||||||
|
calc(var(--sp-4) + env(safe-area-inset-left, 0px));
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto minmax(0, 1fr) auto;
|
||||||
|
grid-template-rows: auto minmax(0, 1fr) auto;
|
||||||
|
grid-template-areas:
|
||||||
|
"title intro done"
|
||||||
|
"list list list"
|
||||||
|
"src src src";
|
||||||
|
column-gap: var(--sp-3);
|
||||||
|
row-gap: var(--sp-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The title, the caveat and the way out share one line, which is the whole of the
|
||||||
|
111px this screen was spending on them. `display: contents` because the three sit
|
||||||
|
in two different boxes in the markup and the sheet's own grid is where they need
|
||||||
|
to be. The sticky positioning goes with the box it is dropping, and is not wanted
|
||||||
|
here: nothing above the list scrolls, so nothing has to stick. */
|
||||||
|
.rulingsHeader {
|
||||||
|
display: contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A grab handle for a sheet that is not a sheet any more. */
|
||||||
|
.rulingsHeader .seatSheetGrip {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rulingsHeader h2 {
|
||||||
|
grid-area: title;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rulingsIntro {
|
||||||
|
grid-area: intro;
|
||||||
|
align-self: center;
|
||||||
|
margin: 0;
|
||||||
|
font-size: var(--fs-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
#closeRulingsBtn {
|
||||||
|
grid-area: done;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Two tracks holding two independent flows, not one flow wrapped into two. That is
|
||||||
|
what the pair of wrappers in the markup buys: a grid with twelve children of its
|
||||||
|
own would pair them into six shared rows, and opening the third ruling on the left
|
||||||
|
would push the ninth down the right-hand side to keep the row square. Here a
|
||||||
|
column only ever moves itself.
|
||||||
|
|
||||||
|
`scrollbar-gutter` because the gutter arrives the moment a ruling is opened, and
|
||||||
|
without the reservation it takes 8px off the tracks and slides the right-hand
|
||||||
|
column sideways while the dealer is reading it. */
|
||||||
|
.rulingsList {
|
||||||
|
grid-area: list;
|
||||||
|
min-height: 0;
|
||||||
|
overflow-y: auto;
|
||||||
|
overscroll-behavior: contain;
|
||||||
|
scrollbar-gutter: stable;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
column-gap: var(--sp-5);
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rulingsColumn {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rulingsSource {
|
||||||
|
grid-area: src;
|
||||||
|
padding-top: var(--sp-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- Short phones, upright ----------
|
/* ---------- Short phones, upright ----------
|
||||||
|
|||||||
@@ -40,6 +40,35 @@ const ruleFor = selector => {
|
|||||||
return CSS.slice(at, CSS.indexOf("}", at));
|
return CSS.slice(at, CSS.indexOf("}", at));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Every @media block written at exactly this condition, concatenated — the same helper
|
||||||
|
// theHeader.test.js uses, and for the same reason: this condition is opened more than
|
||||||
|
// once in the file, and a helper that stops at the first finds a block with none of
|
||||||
|
// these rules in it and reports them missing.
|
||||||
|
const mediaBlock = condition => {
|
||||||
|
const found = [];
|
||||||
|
const needle = "@media ";
|
||||||
|
for (let at = CSS.indexOf(needle); at >= 0; at = CSS.indexOf(needle, at + 1)) {
|
||||||
|
const open = CSS.indexOf("{", at);
|
||||||
|
if (CSS.slice(at + needle.length, open).trim() !== condition) continue;
|
||||||
|
let depth = 0;
|
||||||
|
for (let i = open; i < CSS.length; i++) {
|
||||||
|
if (CSS[i] === "{") depth++;
|
||||||
|
else if (CSS[i] === "}" && --depth === 0) { found.push(CSS.slice(open + 1, i)); break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert.ok(found.length > 0, `no @media block written as "${condition}"`);
|
||||||
|
return found.join("\n");
|
||||||
|
};
|
||||||
|
|
||||||
|
const ruleIn = (block, selector) => {
|
||||||
|
const re = new RegExp(`(^|[},])\\s*${selector.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\s*\\{([^}]*)\\}`, "m");
|
||||||
|
const found = block.match(re);
|
||||||
|
assert.ok(found, `there is no \`${selector}\` rule in that block`);
|
||||||
|
return found[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
const SIDEWAYS = () => mediaBlock("(orientation: landscape) and (max-height: 560px)");
|
||||||
|
|
||||||
// Each ruling as its own slice of markup.
|
// Each ruling as its own slice of markup.
|
||||||
const rulings = () => {
|
const rulings = () => {
|
||||||
const parts = sheet().split('<details class="ruling"');
|
const parts = sheet().split('<details class="ruling"');
|
||||||
@@ -140,3 +169,106 @@ describe("reading one of them", () => {
|
|||||||
assert.match(MAIN, /getElementById\("openRulingsBtn"\)\.addEventListener\("click", openRulings\)/);
|
assert.match(MAIN, /getElementById\("openRulingsBtn"\)\.addEventListener\("click", openRulings\)/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// The dealer who has read the answer has to be able to leave without scrolling back
|
||||||
|
// past it. Measured before this: on a 360x640 phone the twelve shut rulings are 791px of
|
||||||
|
// a 549px sheet, so at the bottom of that scroll Done is 221px above the sheet's top
|
||||||
|
// edge; on a 390x844 phone with one ruling opened — the only reason anybody is in here —
|
||||||
|
// it is 262px. The seat menu's sheet had already been given the fix and this one, the
|
||||||
|
// longer of the two, had not.
|
||||||
|
describe("the way out does not scroll away", () => {
|
||||||
|
test("the header is stuck to the top of the sheet's own scrollport", () => {
|
||||||
|
const rule = ruleFor(".rulingsHeader");
|
||||||
|
assert.match(rule, /position:\s*sticky/);
|
||||||
|
assert.match(rule, /top:\s*0/);
|
||||||
|
// Out to the sheet's edges and back, or the list shows through either side of it.
|
||||||
|
assert.match(rule, /margin:\s*0 calc\(var\(--sp-4\) \* -1\)/);
|
||||||
|
assert.match(rule, /background:\s*var\(--surface-2\)/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("and nothing is left above it for the list to scroll out through", () => {
|
||||||
|
assert.match(ruleFor("#rulingsSheet"), /padding:\s*0 var\(--sp-4\)/,
|
||||||
|
"the sheet keeps a top padding, which is a gap above a sticky header");
|
||||||
|
// The grip was the one thing up there. It belongs inside the header now.
|
||||||
|
const header = sheet().match(/<div class="rulingsHeader">[\s\S]*?<\/div>\s*<\/div>/);
|
||||||
|
assert.ok(header, "the header is not in the markup where it was");
|
||||||
|
assert.match(header[0], /seatSheetGrip/,
|
||||||
|
"the grip is still outside the header, so it scrolls away above it");
|
||||||
|
assert.ok(ruleFor(".rulingsHeader .seatSheetGrip"),
|
||||||
|
"the grip has no rule placing it inside a two-column header");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("the scroll inside the sheet stays inside it", () => {
|
||||||
|
assert.match(ruleFor("#rulingsSheet"), /overscroll-behavior:\s*contain/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// A phone held sideways is 844x390: no height and swimming in width. Measured before
|
||||||
|
// this, the bottom sheet was 460px wide in the middle of that window — 384px of it
|
||||||
|
// unused either side — holding 754px of rulings in a 334px scrollport, 111px of which
|
||||||
|
// went on a title and a caveat that stand still. Four of the twelve names on screen.
|
||||||
|
//
|
||||||
|
// Material's rule for a bottom sheet in landscape is to stop being one, and this tool
|
||||||
|
// already does exactly that under this query for the action bar. So the sheet takes the
|
||||||
|
// window and the width pays for the height: two columns of six, all twelve names on
|
||||||
|
// screen at 844x390 with nothing to scroll at all.
|
||||||
|
describe("a phone on its side gets the whole window", () => {
|
||||||
|
test("the twelve are six and six in the markup", () => {
|
||||||
|
const columns = sheet().split('<div class="rulingsColumn">').slice(1);
|
||||||
|
assert.equal(columns.length, 2, "there are not exactly two columns to stand side by side");
|
||||||
|
columns.forEach((c, i) => {
|
||||||
|
const count = (c.slice(0, c.indexOf("\n </div>")).match(/<details class="ruling"/g) || []).length;
|
||||||
|
assert.equal(count, 6, `column ${i + 1} holds ${count} rulings rather than six`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("but everywhere else they are still one column", () => {
|
||||||
|
// `display: contents` hands the rulings straight to the list, so every layout
|
||||||
|
// that isn't landscape sees exactly the markup it saw before the wrappers.
|
||||||
|
assert.match(ruleFor(".rulingsColumn"), /display:\s*contents/);
|
||||||
|
assert.match(ruleIn(SIDEWAYS(), ".rulingsColumn"), /display:\s*block/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("sideways the sheet stops being a sheet and becomes the screen", () => {
|
||||||
|
const block = SIDEWAYS();
|
||||||
|
assert.match(ruleIn(block, "#rulingsOverlay"), /align-items:\s*stretch/,
|
||||||
|
"the sheet is still anchored to the bottom edge, so it is still short");
|
||||||
|
const sheetRule = ruleIn(block, "#rulingsSheet");
|
||||||
|
assert.match(sheetRule, /height:\s*100%/);
|
||||||
|
assert.match(sheetRule, /max-height:\s*none/);
|
||||||
|
// Capped rather than unbounded: this query also matches a short desktop window,
|
||||||
|
// and two columns of a 1400px one would be 680px lines of body text.
|
||||||
|
assert.match(sheetRule, /max-width:\s*62rem/);
|
||||||
|
assert.match(sheetRule, /overflow:\s*hidden/,
|
||||||
|
"the sheet scrolls as well as the list, which is two scrollbars for one list");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("the title, the caveat and the way out share one line", () => {
|
||||||
|
// That line is the whole of the 111px this screen was spending on them, and the
|
||||||
|
// sticky positioning goes with the box being dropped: nothing above the list
|
||||||
|
// scrolls here, so nothing has to stick.
|
||||||
|
const block = SIDEWAYS();
|
||||||
|
assert.match(ruleIn(block, ".rulingsHeader"), /display:\s*contents/);
|
||||||
|
assert.match(ruleIn(block, ".rulingsHeader .seatSheetGrip"), /display:\s*none/,
|
||||||
|
"a grab handle on a sheet that is not a sheet any more");
|
||||||
|
assert.match(ruleIn(block, "#rulingsSheet"), /grid-template-areas:\s*\n?\s*"title intro done"/);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("the two columns are two flows, not one flow wrapped", () => {
|
||||||
|
// A grid with twelve children of its own pairs them into six shared rows, and
|
||||||
|
// opening the third ruling on the left pushes the ninth down the right-hand side
|
||||||
|
// to keep the row square. Two wrappers means a column only ever moves itself.
|
||||||
|
const rule = ruleIn(SIDEWAYS(), ".rulingsList");
|
||||||
|
assert.match(rule, /grid-template-columns:\s*1fr 1fr/);
|
||||||
|
assert.match(rule, /overflow-y:\s*auto/);
|
||||||
|
assert.match(rule, /min-height:\s*0/,
|
||||||
|
"a grid item's floor is its content, so the list would push the sheet open");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("and the gutter is reserved before it is needed", () => {
|
||||||
|
// It arrives the moment a ruling is opened. Without the reservation it takes 8px
|
||||||
|
// off the tracks and slides the right-hand column sideways under the eye that is
|
||||||
|
// reading it.
|
||||||
|
assert.match(ruleIn(SIDEWAYS(), ".rulingsList"), /scrollbar-gutter:\s*stable/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -957,7 +957,14 @@ const LayoutAudit = {
|
|||||||
// check used to pass it in silence — which is how "Confirm Winner(s)",
|
// check used to pass it in silence — which is how "Confirm Winner(s)",
|
||||||
// the button that pays the pot out, went unmeasured for 36 rounds.
|
// the button that pays the pot out, went unmeasured for 36 rounds.
|
||||||
// Bring it into view before probing.
|
// Bring it into view before probing.
|
||||||
const scroller = el.closest("[style*='overflow'], .modalBody, #potWizardBody, #rulingsSheet, #seatEditorPanel");
|
// `.rulingsList` before `#rulingsSheet`, and `closest` takes the nearer
|
||||||
|
// of the two: on a phone held sideways the sheet fills the window and
|
||||||
|
// stops scrolling, and the twelve rulings scroll inside the list instead.
|
||||||
|
// Naming only the sheet there finds a box whose scrollHeight equals its
|
||||||
|
// clientHeight, decides nothing is out of view, and puts the check back
|
||||||
|
// in the silence this guard exists to break.
|
||||||
|
const scroller = el.closest("[style*='overflow'], .modalBody, #potWizardBody, " +
|
||||||
|
".rulingsList, #rulingsSheet, #seatEditorPanel");
|
||||||
if (scroller && scroller.scrollHeight > scroller.clientHeight) {
|
if (scroller && scroller.scrollHeight > scroller.clientHeight) {
|
||||||
const box = scroller.getBoundingClientRect();
|
const box = scroller.getBoundingClientRect();
|
||||||
const own = el.getBoundingClientRect();
|
const own = el.getBoundingClientRect();
|
||||||
|
|||||||
Reference in New Issue
Block a user