(() => { // catalog links Array.from (document.querySelectorAll ("div.boardlist a")).filter (a => a.hasAttribute ("href")).forEach (a => { const href = a.getAttribute ("href") const ma = href.match (/^(\/[^\/]+\/)(index.html)?$/) let cata = null if (ma != null) { cata = ma [1] + "catalog.html" } if (cata != null) { const e = document.createElement ("a") e.setAttribute ("href", cata) e.innerHTML = "©" if (a.hasAttribute ("title")) { e.setAttribute ("title", a.getAttribute ("title") + " - Catalog") } a.insertAdjacentElement ("afterend", e) } }); // thread stats + Unique IPs (() => { // $('.clear').after($('#thread_stats')) $('#uniqueip > span').attr('style', 'display: block; float: right; margin: 0em 1em;') })(); // post filter individual hiding (() => { const pcid2tid = (board, pcid) => { const n = document.querySelector ('[data-board="' + board + '"].thread > div#' + pcid) return n == null ? null : n.parentNode.getAttribute ('id').replace ('thread_', '') } const merge = (have, posts) => { let changed = false for (const p of posts) { if (!have.some (e => e.post === p.post)) { have.push (p) changed = true } } return changed } const fixids = () => { let lspf = JSON.parse (localStorage.postFilter) let changed = false for (const [board, threads] of Object.entries (lspf.postFilter)) { for (const [id, posts] of Object.entries (threads)) { if (!id.startsWith ('pc')) { continue; } const tid = pcid2tid (board, id) if (tid == null) { continue; } if (tid in threads) { const have = threads [tid] if (merge (have, posts)) { changed = true; } } else { threads [tid] = posts changed = true } delete threads [id] } } if (changed) { lspf = JSON.stringify (lspf) localStorage.postFilter = lspf $(document).trigger('filter_page') } } fixids () $(document).on('filter_page', fixids) // post-filter.js const removepost = function (boardId, threadId, postId) { const list = JSON.parse (localStorage.postFilter) const filter = list.postFilter // thread already pruned if (typeof filter[boardId] == 'undefined' || typeof filter[boardId][threadId] == 'undefined') return; for (var i=0; i { if (!(window.Options && localStorage && document.querySelector ('div.post.op') && Options.get_tab ('webm'))) { return; } const setloopsto = (root, loop) => { if (typeof setupVideosIn === "function") { // expand-video.js const label = loop ? '[loop]' : '[play once]' $(root).find ('p.fileinfo > span').filter ((k, e) => e.innerText === label).each ((k, e) => e.click ()) } else { const flag = loop ? '1' : '0' Array.from (root.querySelectorAll ("div.file > a.file")).filter (e => e.hasAttribute ("href")).map (e => [e, e.getAttribute ("href").match (/^(\/player[.]php[?].+&loop=)([01])$/)]).filter (e_match => e_match [1] != null).forEach (e_match => e_match [0].setAttribute ("href", e_match [1] [1] + flag)) } } const prefix = 'videoloop-' const getcb = (name) => document.getElementById (prefix + name) const checked = (name) => getcb (name).checked const cbset = (name, flag) => { getcb (name).checked = flag; } const addgui = () => { const vlautoset = ((localStorage [prefix + "autoset"] || "false") === "true") const vlonoff = ((localStorage [prefix + "onoff" ] || "true" ) === "true") const gui = '' + _('Loop:') + ' ' + ' ' + ' ' + ''; Options.extend_tab ("webm", gui) cbset ('autoset', vlautoset) cbset ('onoff', vlonoff) $('#' + prefix + 'autoset, #' + prefix + 'onoff').on("change", (ev) => { const cb = ev.target localStorage [cb.getAttribute ("id")] = cb.checked ? "true" : "false" }) $('#' + prefix + 'setnow').on("click", () => { setloopsto (document, checked ('onoff')) }) } addgui() if (checked ('autoset')) { setloopsto (document, checked ('onoff')) } $(document).on('new_post', function (ev, post) { if (checked ('autoset')) { if (typeof setupVideosIn === "function") { // preempt MutationObserver setupVideosIn (post) } setloopsto (post, checked ('onoff')) } }) })(); // top/bottom navlinks (() => { const makea = (href, title, html) => { const a = document.createElement ("a") a.setAttribute ('href', href) a.setAttribute ('title', title) a.innerHTML = html return a } if (document.querySelectorAll ('div.post.op').length == 1) { const span = document.createElement ("span") span.setAttribute ('id', 'topbottom-boardlist-navlinks') span.setAttribute ('style', 'float:right;') span.appendChild (makea ('#top', 'Go to top', '▲')) span.appendChild (makea ('#bottom', 'Go to bottom', '▼')) document.querySelector ('div.boardlist').appendChild (span) } })(); // generic file thumbs Array.from (document.getElementsByTagName ('img')).filter (e => e.hasAttribute ('src')).map (e => [e, e.getAttribute ('src').match (/^\/([^\/]+)\/thumb\/file$/)]).filter (([e, m]) => m != null).forEach (([e, m]) => e.setAttribute ('src', '/static/file.png')); // threadlinks-noup (() => { if (active_page !== "thread") { return; } const added = ' [ Catalog / Home ]' document.querySelector ('div.threadlinks-noup').innerHTML += added })(); })()