jekyll-dice-tray 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e3b5e6ffc89df4600f4c4a25d765e3bc5efcd96d3671817cfc19c0edf540e7f
4
- data.tar.gz: eeb98f0a9a72e5caac9dfa0608f402cfefb90c914c0ecacf2dc170d6484decd8
3
+ metadata.gz: f94a0efe5f9d8e77660ad59f9a455d7639c5c84f0aba09664f26d707bef1ad5f
4
+ data.tar.gz: ae0e7be86f93d73b93753b7394a38e2a0f45b9f77856803775c16b49048464d8
5
5
  SHA512:
6
- metadata.gz: 76359d77b57187df74358db7c49116928b201ce19ffa3130e3af0584087cce008c220baacbea6185f2e5a39686c27b4c78c6010702a9d2576f258158a9df36b7
7
- data.tar.gz: 0b6e4439a8265f518ee925cb7f497fe5c3daa6c2dfd180d67ba8e7dcbefab68495f25bb50805b4d594d2cf777b3f32ed4a9172c5564c512de072db5d80db1ccd
6
+ metadata.gz: f6a7a8507c6a193051373cb66ae7b6f7a71f911e87ac7c01a172c0ba26b62b5eb76793212ca38da475a64ff0bad0572de1518e9f12bb6088aff2f615580e2ed4
7
+ data.tar.gz: 7f3c908b2eee3946f710de9af643e79dd9d001eeb7838654cb818defd6b921f8b33025950a07ad782eb7619af96f471650fb9043c77e115a9b857619acd73179
data/README.md CHANGED
@@ -4,7 +4,7 @@ A Jekyll plugin gem that:
4
4
 
5
5
  - Adds an overlay dice tray that accepts dice rolling input
6
6
  - Recognizes dice expressions in rendered pages like `d4`, `1d6`, `1d20+1` and turns them into clickable links that roll in the tray
7
- - Clicking a lookup-table die (any `dN`) rolls and shows the matching entry — supports any number of side-by-side key/value column groups, ranges like `3–12`, and tables with or without headers. One die in the header searches the whole table; multiple dice each search their own column group
7
+ - Clicking a lookup-table die (any `dN`) rolls and shows the matching entry — supports any number of side-by-side key/value column groups, ranges like `3–12`, and tables with or without headers. Header dice always search the whole table (side-by-side column groups included)
8
8
  - Persists input history, result history, minimize status
9
9
 
10
10
  https://github.com/user-attachments/assets/6ef8d788-a1ee-49d4-ab26-f63899bb4a10
@@ -34,13 +34,16 @@
34
34
  border-radius: 12px;
35
35
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.22);
36
36
  overflow: hidden;
37
- display: flex;
37
+ /* Stay collapsed until data-expanded="true". A default of flex overrides the
38
+ hidden attribute and paints the open tray before hydration. */
39
+ display: none;
38
40
  flex-direction: column;
39
41
  max-height: 360px;
40
42
  }
41
43
 
42
- #jekyll-dice-tray[data-expanded="false"] .jdt-body {
43
- display: none;
44
+ /* Only the pre-paint script or dice_tray.js sets this; absent means minimized. */
45
+ #jekyll-dice-tray[data-expanded="true"] .jdt-body {
46
+ display: flex;
44
47
  }
45
48
 
46
49
  #jekyll-dice-tray .jdt-clue {
@@ -2,6 +2,7 @@
2
2
  "use strict";
3
3
 
4
4
  var STORAGE_PREFIX = "jekyll_dice_tray:";
5
+ // Also read before first paint by the inline script in HtmlRewriter.inject_tray.
5
6
  var STORAGE_EXPANDED = STORAGE_PREFIX + "expanded";
6
7
  var STORAGE_HISTORY = STORAGE_PREFIX + "history_v1";
7
8
  var STORAGE_INPUT_HISTORY = STORAGE_PREFIX + "input_history_v1";
@@ -179,14 +180,6 @@
179
180
  return Array.prototype.slice.call(row.querySelectorAll("td, th"));
180
181
  }
181
182
 
182
- function cellColumnIndex(row, cell) {
183
- var cells = rowCells(row);
184
- for (var i = 0; i < cells.length; i++) {
185
- if (cells[i] === cell) return i;
186
- }
187
- return -1;
188
- }
189
-
190
183
  function rowLooksLikeHeader(row) {
191
184
  if (!row) return false;
192
185
  if (row.querySelector("th")) return true;
@@ -269,13 +262,11 @@
269
262
  return max;
270
263
  }
271
264
 
272
- function collectRowEntriesForGroups(row, groups, allowedKeyIndices) {
265
+ function collectRowEntriesForGroups(row, groups) {
273
266
  var cells = rowCells(row);
274
267
  var entries = [];
275
- var allowAll = !allowedKeyIndices || !allowedKeyIndices.length;
276
268
  for (var g = 0; g < groups.length; g++) {
277
269
  var group = groups[g];
278
- if (!allowAll && allowedKeyIndices.indexOf(group.keyIndex) === -1) continue;
279
270
  var keyCell = cells[group.keyIndex];
280
271
  if (!keyCell) continue;
281
272
  var key = parseKeyEntry(normalizeCellText(keyCell));
@@ -302,16 +293,17 @@
302
293
  if (!table || !groups || !groups.length) return false;
303
294
  var matches = 0;
304
295
  eachDataRow(table, headerRow, function (row) {
305
- matches += collectRowEntriesForGroups(row, groups, null).length;
296
+ matches += collectRowEntriesForGroups(row, groups).length;
306
297
  });
307
298
  return matches >= 2;
308
299
  }
309
300
 
310
- function findLookupMatch(table, headerRow, groups, rollTotal, allowedKeyIndices) {
301
+ // Header dice (one or many side-by-side) always search every key column in the table.
302
+ function findLookupMatch(table, headerRow, groups, rollTotal) {
311
303
  var exact = null;
312
304
  var range = null;
313
305
  eachDataRow(table, headerRow, function (row) {
314
- var entries = collectRowEntriesForGroups(row, groups, allowedKeyIndices);
306
+ var entries = collectRowEntriesForGroups(row, groups);
315
307
  for (var e = 0; e < entries.length; e++) {
316
308
  var entry = entries[e];
317
309
  if (entry.key.kind === "exact" && entry.key.value === rollTotal) {
@@ -329,45 +321,18 @@
329
321
  return exact || range;
330
322
  }
331
323
 
332
- function headerDiceCount(headerRow) {
333
- if (!headerRow) return 0;
334
- return headerRow.querySelectorAll('a[data-dice]').length;
335
- }
336
-
337
- function groupForColumn(groups, columnIndex) {
338
- for (var g = 0; g < groups.length; g++) {
339
- var group = groups[g];
340
- if (columnIndex === group.keyIndex) return group;
341
- if (group.valueIndices.indexOf(columnIndex) !== -1) return group;
342
- }
343
- return null;
344
- }
345
-
346
- // One die in the header (e.g. d100 over many pairs) => search every group.
347
- // Several dice (e.g. d10 | Weather | d10 | Terrain | d6 | Mood) => only the clicked group.
348
- function allowedKeyIndicesForClick(headerRow, clickCell, groups) {
349
- if (!headerRow || !clickCell || !groups.length) return null;
350
- if (headerDiceCount(headerRow) <= 1) return null;
351
- var col = cellColumnIndex(headerRow, clickCell);
352
- if (col < 0) return null;
353
- var group = groupForColumn(groups, col);
354
- return group ? [group.keyIndex] : null;
355
- }
356
-
357
324
  function getLookupTableContext(anchor, rollTotal) {
358
325
  if (!anchor || !anchor.closest || rollTotal == null) return null;
359
326
 
360
327
  var cell = null;
361
328
  var table = null;
362
329
  var headerRow = null;
363
- var allowedKeys = null;
364
330
  var sourceTable = anchor._jdtSourceTable;
365
331
 
366
332
  if (sourceTable && sourceTable.querySelector) {
367
333
  // Re-roll from a previous table result in the tray.
368
334
  table = sourceTable;
369
335
  headerRow = findTableHeaderRow(table);
370
- allowedKeys = anchor._jdtAllowedKeyIndices || null;
371
336
  } else {
372
337
  cell = anchor.closest("td, th");
373
338
  if (!cell) return null;
@@ -384,10 +349,7 @@
384
349
  var groups = buildColumnGroups(keyColumns, tableColumnCount(table, headerRow));
385
350
  if (!isLookupTable(table, headerRow, groups)) return null;
386
351
 
387
- if (allowedKeys == null && cell && headerRow) {
388
- allowedKeys = allowedKeyIndicesForClick(headerRow, cell, groups);
389
- }
390
- var matched = findLookupMatch(table, headerRow, groups, rollTotal, allowedKeys);
352
+ var matched = findLookupMatch(table, headerRow, groups, rollTotal);
391
353
  if (!matched) return null;
392
354
 
393
355
  var headerCells = headerRow ? rowCells(headerRow) : [];
@@ -420,9 +382,7 @@
420
382
  });
421
383
  }
422
384
 
423
- return columns.length
424
- ? { columns: columns, _sourceTable: table, _allowedKeyIndices: allowedKeys }
425
- : null;
385
+ return columns.length ? { columns: columns, _sourceTable: table } : null;
426
386
  }
427
387
 
428
388
  function serializableTableContext(tableContext) {
@@ -459,9 +419,6 @@
459
419
  if (tableContext._sourceTable && tableContext._sourceTable.querySelector) {
460
420
  reroll._jdtSourceTable = tableContext._sourceTable;
461
421
  }
462
- if (tableContext._allowedKeyIndices) {
463
- reroll._jdtAllowedKeyIndices = tableContext._allowedKeyIndices;
464
- }
465
422
  headerSpan.appendChild(reroll);
466
423
  } else if (col.header_html) {
467
424
  headerSpan.innerHTML = col.header_html;
@@ -565,6 +522,7 @@
565
522
  root.setAttribute("data-expanded", expanded ? "true" : "false");
566
523
  // Some themes override [hidden], so enforce display too.
567
524
  body.hidden = !expanded;
525
+ // Clear the pre-paint inline lock so the expanded stylesheet rule can show the body.
568
526
  body.style.display = expanded ? "" : "none";
569
527
  saveBool(STORAGE_EXPANDED, expanded);
570
528
  if (expanded) {
@@ -199,18 +199,42 @@ module Jekyll
199
199
  def self.inject_tray(html, assets_path:)
200
200
  return html if html.include?('data-dice-tray-root="true"')
201
201
 
202
+ # Start collapsed. Inline display:none holds the body shut until the script
203
+ # below runs: the hidden attribute loses to author CSS (including ours), and
204
+ # the deferred dice_tray.js can run after first paint, which flashes the
205
+ # open tray on navigation. This script reads the same localStorage key as
206
+ # STORAGE_EXPANDED in dice_tray.js and applies it before first paint.
202
207
  tray = <<~HTML
203
- <div id="jekyll-dice-tray" data-dice-tray-root="true" data-version="#{VERSION}" aria-live="polite">
208
+ <div id="jekyll-dice-tray" data-dice-tray-root="true" data-version="#{VERSION}" data-expanded="false" aria-live="polite">
204
209
  <div class="jdt-header">
205
210
  <button type="button" class="jdt-toggle" aria-expanded="false" title="Toggle dice tray">Dice</button>
206
211
  </div>
207
- <div class="jdt-body" hidden>
212
+ <div class="jdt-body" hidden style="display:none">
208
213
  <div class="jdt-clue">Type <code>1d20+5</code> or <code>/help</code>, then press Enter.</div>
209
214
  <div class="jdt-log" role="log" aria-label="Dice roll log"></div>
210
215
  <input class="jdt-input" type="text" inputmode="text" autocomplete="off" spellcheck="false"
211
216
  placeholder="Roll: 1d6, d4, 2d8+1, /help" />
212
217
  </div>
213
218
  </div>
219
+ <script>
220
+ // Synchronous on purpose: must finish before the browser paints the tray.
221
+ (function () {
222
+ try {
223
+ // Keep in sync with STORAGE_EXPANDED in dice_tray.js.
224
+ var expanded = localStorage.getItem("jekyll_dice_tray:expanded") === "true";
225
+ var root = document.getElementById("jekyll-dice-tray");
226
+ if (!root) return;
227
+ root.setAttribute("data-expanded", expanded ? "true" : "false");
228
+ var toggle = root.querySelector(".jdt-toggle");
229
+ if (toggle) toggle.setAttribute("aria-expanded", expanded ? "true" : "false");
230
+ var body = root.querySelector(".jdt-body");
231
+ if (!body) return;
232
+ body.hidden = !expanded;
233
+ // Inline display wins over theme rules that override [hidden].
234
+ body.style.display = expanded ? "flex" : "none";
235
+ } catch (e) {}
236
+ })();
237
+ </script>
214
238
  HTML
215
239
 
216
240
  tags = <<~HTML
@@ -1,6 +1,6 @@
1
1
  module Jekyll
2
2
  module DiceTray
3
- VERSION = "0.5.0"
3
+ VERSION = "0.5.2"
4
4
  end
5
5
  end
6
6
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-dice-tray
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - directsun