(() => { // 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) } }); // batch video loop/once (() => { if (!(window.Options && window.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) } })(); // threadlinks-noup (() => { if (active_page !== "thread") { return; } const added = ' [ Catalog / Home ]' document.querySelector ('div.threadlinks-noup').innerHTML += added })(); // quick reply spoiler sync (() => { const cbsync = (form1, form2, name) => { const sel = 'input[type="checkbox"][name="' + name + '"]' const cb1 = form1.find (sel) const cb2 = form2.find (sel) cb1.on ('change', () => { cb2.prop ('checked', cb1.prop ('checked')) }) cb2.on ('change', () => { cb1.prop ('checked', cb2.prop ('checked')) }) } const spoilersync = () => { const ftop = $('form[name="post"]:first') const fquick = $('#quick-reply') if ((ftop.length != 1) || (fquick.length != 1)) { return; } if (fquick.attr ('data-userjs-spoilersync') == 'spoilersync') { return; } cbsync (ftop, fquick, 'spoiler') fquick.attr ('data-userjs-spoilersync', 'spoilersync') } spoilersync () $(window).on('quick-reply', spoilersync) })(); })()