PageSourceSearch

https://ward2u.com/ward.js?v=260821ww

js ward2u.com collected 2026-10-02 13:45:34 UTC 6,637 bytes, 156 lines download raw bytes

1(function () {
2  "use strict";
3
4  /* --- 1. dead frames -------------------------------------------------------
5     The inline handler (wDrop, declared in <head>) does the work: first failure
6     swaps the Photon url for the origin one, second failure removes the frame.
7     This sweep only catches what the handler cannot: a frame that answered 200
8     with a 1x1 pixel, and frames that die after the last error event. The
9     viewer's own <img> starts as a 1x1 gif, so it is NOT in this selector. */
10  function sweep() {
11    var imgs = document.querySelectorAll(".frame img, [data-set] img, .story img");
12    for (var n = 0; n < imgs.length; n++) {
13      var im = imgs[n];
14      if (im.complete && im.naturalWidth <= 1 && window.wDrop) window.wDrop(im);
15    }
16  }
17
18  /* --- 2. no ragged last row ------------------------------------------------
19     Tiles remove themselves when they die, so a grid that was flush in the
20     markup ends in a half-empty strip of bare ground. Rows are grouped by
21     offsetTop, which works at every breakpoint and with a banner tile that
22     spans the whole width; only a SHORT last row is dropped. */
23  function trimTail(wall) {
24    var kids = Array.prototype.slice.call(wall.children);
25    if (kids.length < 4) return;
26    var rows = {}, i, t;
27    for (i = 0; i < kids.length; i++) {
28      t = Math.round(kids[i].offsetTop);
29      (rows[t] = rows[t] || []).push(kids[i]);
30    }
31    var tops = Object.keys(rows).map(Number).sort(function (a, b) { return a - b; });
32    if (tops.length < 2) return;
33    var full = 0;
34    for (i = 0; i < tops.length; i++) full = Math.max(full, rows[tops[i]].length);
35    var last = rows[tops[tops.length - 1]];
36    if (last.length < full) for (i = 0; i < last.length; i++) last[i].remove();
37  }
38
39  /* A record whose FIRST frame is dead would open with no lead at all — about one
40     record in twelve. Promote the first surviving strip frame instead, so the
41     scale hierarchy holds on every record and not merely on most. */
42  function keepLead() {
43    var set = document.querySelector("[data-set]");
44    if (!set || set.querySelector(".lead")) return;
45    var first = set.querySelector(".strip__track figure");
46    if (!first) return;
47    first.className = "lead";
48    set.insertBefore(first, set.firstChild);
49  }
50
51  /* The ledger counts what is ON THE PAGE, not what the server sent: frames drop
52     out, and a count that keeps claiming twenty is simply untrue. */
53  function count() {
54    var box = document.querySelector("[data-set], .story");
55    var el = document.querySelector("[data-frames]");
56    if (box && el) el.textContent = box.querySelectorAll("img").length;
57    Array.prototype.forEach.call(document.querySelectorAll("[data-trim]"), function (wall) {
58      var led = wall.previousElementSibling;
59      var slot = led && led.querySelector("[data-count]");
60      if (slot) slot.textContent = wall.children.length + " sets";
61    });
62  }
63
64  function pass() {
65    sweep();
66    keepLead();
67    var walls = document.querySelectorAll("[data-trim]");
68    for (var n = 0; n < walls.length; n++) trimTail(walls[n]);
69    count();
70  }
71  /* a frame that dies after the last scheduled pass re-opens the ragged row, and
72     lazy tiles below the fold die only once the reader scrolls to them — so every
73     removal asks for one more pass instead of hoping the timers covered it */
74  window.wAfterDrop = function () {
75    clearTimeout(window.__wardTr);
76    window.__wardTr = setTimeout(pass, 700);
77  };
78  [700, 1800, 4000, 9000].forEach(function (ms) { setTimeout(pass, ms); });
79  window.addEventListener("pageshow", pass);
80  window.addEventListener("resize", function () {
81    clearTimeout(window.__wardRz);
82    window.__wardRz = setTimeout(pass, 400);
83  });
84
85  /* --- 3. the viewer: same frame, own code, no CDN -------------------------- */
86  var box = document.getElementById("ward-viewer");
87  var stage = box ? box.querySelector(".viewer__stage > img") : null;
88  var tally = box ? box.querySelector(".viewer__count") : null;
89  var reel = [], at = -1;
90
91  function place(k) {
92    if (!reel.length) return;
93    at = (k + reel.length) % reel.length;
94    var from = reel[at];
95    stage.src = from.currentSrc || from.src;
96    stage.alt = from.alt || "";
97    if (tally) tally.textContent = (at + 1) + " / " + reel.length;
98  }
99  function ahead() { place(at + 1); }
100  function back() { place(at - 1); }
101
102  function raise(scope, hit) {
103    if (!box || typeof box.showModal !== "function") return;
104    reel = Array.prototype.slice.call(scope.querySelectorAll("img")).filter(function (im) {
105      return im.isConnected;
106    });
107    var k = reel.indexOf(hit);
108    place(k < 0 ? 0 : k);
109    box.showModal();
110  }
111
112  Array.prototype.forEach.call(document.querySelectorAll("[data-viewer]"), function (scope) {
113    scope.addEventListener("click", function (e) {
114      var hit = e.target;
115      if (hit && hit.tagName === "IMG" && hit.isConnected) {
116        e.preventDefault();
117        raise(scope, hit);
118      }
119    });
120  });
121
122  if (box) {
123    box.querySelector(".viewer__next").addEventListener("click", ahead);
124    box.querySelector(".viewer__prev").addEventListener("click", back);
125    box.querySelector(".viewer__x").addEventListener("click", function () { box.close(); });
126    box.addEventListener("click", function (e) { if (e.target === box) box.close(); });
127    box.addEventListener("keydown", function (e) {
128      if (e.key === "ArrowRight") ahead();
129      else if (e.key === "ArrowLeft") back();
130    });
131  }
132
133  /* --- 4. film strip -------------------------------------------------------- */
134  Array.prototype.forEach.call(document.querySelectorAll(".strip"), function (strip) {
135    var track = strip.querySelector(".strip__track");
136    if (!track) return;
137    function nudge(way) {
138      var one = track.querySelector("figure");
139      var w = one ? one.getBoundingClientRect().width + 6 : 300;
140      track.scrollBy({ left: way * w, behavior: "smooth" });
141    }
142    var p = strip.querySelector('[data-strip="prev"]'), n = strip.querySelector('[data-strip="next"]');
143    if (p) p.addEventListener("click", function () { nudge(-1); });
144    if (n) n.addEventListener("click", function () { nudge(1); });
145  });
146
147  /* --- 5. role-6 pages carry no page-type IF, so the layout can only give them
148     the bare brand. Each legal page names itself here. ----------------------- */
149  var slip = document.querySelector("[data-title]");
150  if (slip) {
151    document.title = slip.getAttribute("data-title");
152    var d = slip.getAttribute("data-desc");
153    var m = document.querySelector('meta[name="description"]');
154    if (d && m) m.setAttribute("content", d);
155  }
156})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.