- // ==UserScript==
- // @name FastTech Forum Enhancements
- // @namespace ftil
- // @description Improvements for the FastTech forums and store
- // @include https://*.fasttech.com/*
- // @version 2.5.1
- // @grant GM_getValue
- // @grant GM_setValue
- // @run-at document-start
- // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAOVBMVEVMaXEega+SlJeSkpgggK+Tk5gfgq+SlJeSkpkegK8egK8fgK+Tk5d1jZ6SkpcfgLEegLCTlJgfgbBPYHHZAAAAEXRSTlMApS2cl95Qi1CMvOmzFGgsdPNojJcAAACSSURBVHgBzdJlAgIwCAbQb915/7vaumG3vt8DRuAmIwheJOGQ2ywCvs8qYMVgsFLZSuiBrWhc4jsD8cIDrgh++qDNDM49MHmP4+wDDuIPHyRrE04VXbBlqZQ0hdhmKqXQZwwQaogcKD4MEt+QDMGLo8BvHe3qQTwwAJJjgyajPu/9Dwoj5MmDky6SEAlElYPGTUsirRDoa4UEWgAAAABJRU5ErkJggg==
- // ==/UserScript==
- 'use strict';
- // Delay function calls until their preconditions have been met.
- var block = (function() {
- var counters = { };
-
- return {
- get: function(name) { return counters[name].val !== 0; },
-
- block: function(name) {
- var c = counters[name];
- if (c === undefined)
- counters[name] = { val: 1, watches: [] };
- else if (c.val !== 0)
- c.val++;
- },
-
- unblock: function(name) {
- var c = counters[name];
- if (c.val !== 0)
- c.val--;
- if (c.val === 0) {
- var w = c.watches;
- while (w.length !== 0)
- w.shift()();
- }
- },
-
- watch: function(name, func) {
- var c = counters[name];
- if (c.val !== 0)
- c.watches.push(func);
- else
- func();
- },
- };
- })();
- /* Userscript settings:
- * This is just terrible. GM_[sg]etValue is used to initialize settings since
- * it's shared across subdomains, while localStorage is used to notify other
- * tabs of new settings.
- */
- var settings = (function() {
- var settings = { };
- var watches = { };
- var prefix = 'ignore_list:';
- var prere = new RegExp('^' + prefix + '(.+)');
- var have_ls = (function() {
- try {
- localStorage.getItem('test');
- return true;
- } catch (e) {
- return false;
- }
- })();
-
- // Unblock after execution of the script
- block.block('ready');
-
- function inner_set(name, value) {
- // Ugh.
- if (JSON.stringify(settings[name].value) === JSON.stringify(value))
- return false;
- settings[name].value = value;
- if (name in watches) {
- var w = watches[name];
- for (var i = 0; i < w.length; i++)
- w[i](name, value);
- }
- return true;
- }
-
- if (have_ls) {
- window.addEventListener('storage', function(e) {
- var set = e.key.match(prere);
- if (set !== null && set[1] in settings)
- inner_set(set[1], JSON.parse(e.newValue));
- });
- }
-
- function get_sync(name) {
- var val = GM_getValue(name, null);
- if (val !== null)
- return JSON.parse(val);
- else
- return settings[name].def;
- }
-
- return {
- get: function(name) { return settings[name].value; },
- get_sync: get_sync,
-
- set: function(name, value) {
- if (inner_set(name, value)) {
- var s = JSON.stringify(value);
- if (have_ls)
- localStorage.setItem(prefix + name, s);
- GM_setValue(name, s);
- }
- },
-
- all: function() { return settings; },
-
- register: function(name, desc, def, dep, opt) {
- settings[name] = {
- desc: desc,
- def: def,
- dep: dep,
- opt: opt,
- };
- inner_set(name, get_sync(name));
- },
-
- watch: function(name, func) {
- if (!(name in watches))
- watches[name] = [];
- watches[name].push(func);
- if (settings[name] !== undefined)
- func(name, settings[name].value);
- },
-
- update: function() { block.unblock('ready'); },
- };
- })();
- // Dynamic stylesheets
- var styles = (function() {
- var urls = {};
- var txts = {};
- var elms = {};
- var active_elm;
-
- function try_gmgrt(name) {
- try {
- return GM_getResourceText('theme_' + name);
- } catch (e) {}
- }
-
- function apply() {
- var enable = settings.get('use_theme');
- var name = settings.get('theme_name');
-
- if (enable === true && name !== undefined) {
- if (active_elm !== undefined) {
- if (active_elm === elms[name])
- return;
- active_elm.disabled = true;
- }
-
- if (name in elms) {
- elms[name].disabled = false;
- } else {
- var e, u;
- var c = try_gmgrt(name);
- if (c === undefined || c === null) {
- u = urls[name];
- c = txts[name];
- }
- if (c !== undefined) {
- e = document.createElement('style');
- e.type = 'text/css';
- e.innerHTML = c;
- } else {
- e = document.createElement('link');
- e.rel = 'stylesheet';
- e.type = 'text/css';
- e.href = u;
- }
- document.head.appendChild(e);
- elms[name] = e;
- }
-
- active_elm = elms[name];
- } else if (active_elm !== undefined) {
- active_elm.disabled = true;
- active_elm = undefined;
- }
- }
-
- return {
- register: function(name, url, txt) {
- if (url !== undefined)
- urls[name] = url;
- if (txt !== undefined)
- txts[name] = txt;
- },
-
- update: function() {
- settings.watch('use_theme', apply);
- settings.watch('theme_name', apply);
- },
- };
- })();
- // Sanitize external values that may be fed into an innerHTML
- var strip_tags = (function() {
- var div = document.createElement('div');
- return function(t) {
- div.innerHTML = t;
- return div.textContent;
- };
- })();
-
- // Case-insensitive indexOf (needed in case of case errors in user input)
- function ci_indexof(a, n) {
- var l = n.toLowerCase();
- for (var i = 0; i < a.length; i++) {
- if (a[i].toLowerCase() === l)
- return i;
- }
- return -1;
- }
-
- // Case-insensitive attribute lookup
- function ci_lookup(a, n) {
- var l = n.toLowerCase();
- for (var k in a) {
- if (k.toLowerCase() === l)
- return k;
- }
- }
- // Assorted generic handlers for user input.
- var handlers = (function() {
- function Handler(funcs, elm, data, extra) {
- this.elm = elm;
- this.data = data;
- this.extra = extra;
- if (funcs.setting !== undefined)
- settings.watch(data, funcs.setting.bind(this));
- for (var k in funcs) {
- if (k.slice(0, 2) === 'on')
- elm.addEventListener(k.slice(2), funcs[k].bind(this));
- }
- }
-
- function handler(fs) {
- return function(e, d, x) { return new Handler(fs, e, d, x); };
- }
-
- return {
- generic: handler,
-
- ignore_toggle: handler({
- onclick: function() { ignore_list.set(this.data); }
- }),
-
- checkbox: handler({
- onchange: function() { settings.set(this.data, this.elm.checked); },
- setting: function(n, v) { this.elm.checked = v; }
- }),
-
- top_click: handler({
- onclick: function() { scrollTo(0, 0); }
- }),
-
- hide_toggle: handler({
- onclick: function() { unhide_posts.set(this.data); }
- }),
- };
- })();
- // Manage the state of the ignore list
- function create_ignore_list(list_var) {
- // Use two stages so that filters can handle updates before being called
- var watches = { 'early': [], 'late': [] };
- var il = [];
-
- function fire_watches(user, state, idx) {
- ['early', 'late'].forEach(function(stage) {
- var w = watches[stage];
- for (var i = 0; i < w.length; i++)
- w[i](user, state, idx);
- });
- }
-
- function inner_set(user, state, idx) {
- // In order to support userscripts, we need to rebuild the list on every set
- if (settings.get_sync) {
- il = [];
- var l = settings.get_sync(list_var);
- for (var i = 0; i < l.length; i++)
- il.push(l[i]);
- }
- if (state)
- il.push(user);
- else
- il.splice(idx, 1);
- settings.set(list_var, il);
- fire_watches(user, state, idx);
- }
-
- settings.register(list_var, null, [], null);
- // Watch for ignorelist changes, and fire incremental watch events
- settings.watch(list_var, function(name, val) {
- var i, j;
- if (il.length === val.length)
- return;
- if (il.length === 0) {
- for (i = 0; i < val.length; i++)
- il.push(val[i]);
- fire_watches(il, true);
- return;
- }
- i = 0;
- j = 0;
- while (true) {
- if (il[i] === undefined && val[j] === undefined)
- break;
- if (il[i] !== val[j]) {
- var user, state, idx;
- if (il[i] === undefined) {
- // New entry @ end of list: user added
- user = val[j];
- il.push(user);
- state = true;
- idx = i;
- } else {
- // Missing entry inside list: user removed
- user = il[i];
- il.splice(i, 1);
- state = false;
- idx = i;
- }
- fire_watches(user, state, idx);
- continue;
- }
- i++;
- j++;
- }
- });
-
- return {
- // Get ignored state of user (true == ignored)
- get: function(user) { return (ci_indexof(il, user) !== -1); },
-
- // Set ignored state of user (undefined == toggle)
- set: function(user, state) {
- var idx = ci_indexof(il, user);
- if (state === undefined)
- state = (idx === -1);
- if ((state && (idx === -1)) || (!state && (idx !== -1)))
- inner_set(user, state, idx);
- },
-
- /* Watch the ignorelist for changes (stage == ('early'|'late')).
- * func may be called with a single user and a new state, or an array of
- * users (with implicit ignored state for all)
- */
- watch: function(stage, func) {
- watches[stage].push(func);
- if (il !== [])
- func(il, true, -1);
- },
- };
- }
- /* Core post filtering logic
- * post vars are expected to be in the format
- * { user: string, content_elm: element, post_elms: [element] }
- */
- var post_filter = (function() {
- var posts;
- var watches = [];
- var filters;
-
- settings.register('hide_ignored', 'Hide posts by ignored users', true, null);
- block.block('filter');
-
- function update() {
- if (posts === undefined)
- return;
-
- for (var i = 0; i < posts.length; i++) {
- var post = posts[i];
- var hide = false;
- var j;
- for (j = 0; j < filters.length; j++) {
- var tmp = filters[j](post);
- if (tmp === true) {
- hide = true;
- } else if (tmp === false) {
- hide = false;
- break;
- }
- }
-
- var display = hide ? 'none' : '';
- for (j = 0; j < post.post_elms.length; j++)
- post.post_elms[j].style.display = display;
-
- for (j = 0; j < watches.length; j++)
- watches[j](post, hide);
- }
-
- block.unblock('filter');
- }
-
- function builtin() {
- filters = [];
- filters.unshift((function() {
- settings.watch('hide_ignored', post_filter.update);
- ignore_list.watch('late', post_filter.update);
-
- return function(post) {
- if (settings.get('hide_ignored') && ignore_list.get(post.user))
- return true;
- };
- })());
- unhide_posts = (function() {
- var posts = [];
-
- filters.unshift(function(post) {
- if (posts.indexOf(post) !== -1)
- return false;
- });
-
- return {
- // Set the unhide state of a post (true == unhide, undefined == toggle)
- set: function(post, state) {
- var idx = posts.indexOf(post);
- if (state === undefined)
- state = (idx === -1);
- if (state && idx === -1)
- posts.push(post);
- else if (!state && idx !== -1)
- posts.splice(idx, 1);
- else
- return;
- post_filter.update();
- }
- };
- })();
- }
-
- return {
- // Register a list of posts to be filtered
- register: function(list) {
- posts = list;
- update();
- },
-
- /* Add a new filter. Filters return true (should hide), false (must not
- * hide), or undefined (no judgement). Does not trigger update().
- */
- filter: function(func) {
- if (filters === undefined)
- builtin();
- filters.push(func);
- },
- // Run all filters again
- update: update,
-
- /* Call func with changes to the hidden status of each post (true ==
- * hidden). Does not trigger update().
- */
- watch: function(func) { watches.push(func); },
- };
- })();
-
- var unhide_posts;
- // Generic buttons to toggle ignored state of a user
- var ignore_buttons = (function() {
- var posts;
- var inner_ign = '';
- var inner_unign = '';
-
- function update_btns(users, state) {
- var i;
- if (users instanceof Array) {
- for (i = 0; i < posts.length; i++) {
- posts[i].ignbtn.innerHTML =
- ci_indexof(users, posts[i].user) !== -1 ? inner_unign : inner_ign;
- }
- } else {
- var ul = users.toLowerCase();
- for (i = 0; i < posts.length; i++) {
- if (!ul.localeCompare(posts[i].user.toLowerCase()))
- posts[i].ignbtn.innerHTML = state ? inner_unign : inner_ign;
- }
- }
- }
-
- return {
- // Set the (HTML) format of the (un)ignore buttons
- set: function(ign, unign) {
- inner_ign = ign;
- inner_unign = unign;
- },
-
- // Register posts to have their ignore buttons handled
- register: function(p) {
- posts = p;
- for (var i = 0; i < p.length; i++)
- handlers.ignore_toggle(p[i].ignbtn, p[i].user);
- ignore_list.watch('late', update_btns);
- },
- };
- })();
- // Handle RES-style tagging of users
- var user_tags = (function() {
- var posts;
-
- function update_badges(n, val) {
- for (var i = 0; i < posts.length; i++) {
- var post = posts[i];
- var k = ci_lookup(val, post.user);
- post.badge.innerHTML = k !== undefined ? val[k] : post.saved_badge;
- }
- }
-
- var tag_prompt = handlers.generic({ onclick: function(e) {
- e.preventDefault();
- e.stopPropagation();
-
- var user = this.data;
- var tmp =
- (settings.get_sync ? settings.get_sync : settings.get)('user_tags');
- var def = '';
- if (tmp[user] !== undefined)
- def = tmp[user];
- var tag = prompt('Tag for ' + user + ' or blank for default:', def);
- if (tag === null)
- return;
- tag = strip_tags(tag);
-
- // Ugh.
- var tags = { };
- for (var u in tmp)
- tags[u] = tmp[u];
-
- if (tags[user] !== undefined && tag === '')
- delete tags[user];
- else if (tag !== '')
- tags[user] = tag;
- settings.set('user_tags', tags);
- }});
-
- return {
- // Register posts to have their badges handled
- register: function(p) {
- posts = p;
- for (var i = 0; i < p.length; i++) {
- var post = p[i];
- post.saved_badge = post.badge.innerHTML;
- tag_prompt(post.badge, post.user);
- }
- settings.watch('user_tags', update_badges);
- },
-
- update: function() {
- settings.register('user_tags', null, { }, null);
- },
- };
- })();
- // Track the last viewed page and post count for threads
- var last_viewed = (function() {
- var db;
- var store = 'thread_data';
-
- function GetCmd(args) { this.args = args; }
- GetCmd.prototype.mode = 'readonly';
- GetCmd.prototype.success = function(e) {
- var t = e.target.result;
- if (t !== undefined)
- this.args.f(this.args.e, t.lvp, t.lpn, t.lp);
- };
- function SetCmd(args) { this.args = args; }
- SetCmd.prototype.mode = 'readwrite';
- SetCmd.prototype.success = function(e) {
- var t = e.target.result;
- if (t === undefined)
- t = {id: this.args.id};
- t.lvt = this.args.lvt;
- t.lvp = this.args.lvp;
- if (t.lpn === undefined || t.lpn < this.args.lpn) {
- t.lpn = this.args.lpn;
- t.lp = this.args.lp;
- }
- this.os.put(t);
- };
- GetCmd.prototype.exec = SetCmd.prototype.exec = function() {
- this.os = db.transaction(store, this.mode).objectStore(store);
- this.os.get(this.args.id).onsuccess = this.success.bind(this);
- };
-
- // Accumulate commands and fire them once idb is open
- var cmds = [];
- function run_cmds() {
- if (db === undefined || db === null)
- return open_db();
-
- var cmd;
- while ((cmd = cmds.shift()) !== undefined)
- cmd.exec();
- }
-
- // Open idb and maybe remove old threads
- function open_db() {
- if (db === undefined)
- db = null;
- else
- return;
- var req = indexedDB.open('ignore_list', 2);
- req.onupgradeneeded = function(e) {
- var tmp = e.target.result;
- if (!tmp.objectStoreNames.contains(store)) {
- var os = tmp.createObjectStore(store, { keyPath: 'id' });
- os.createIndex('lvt', 'lvt');
- }
- };
- req.onsuccess = function(e) {
- db = e.target.result;
- run_cmds();
-
- /* Periodically scrub the database (FIXME this is awful & may run in
- * multiple tabs simultaneously)
- */
- settings.register('lv_scrub_time', null, 0, null);
- settings.watch('lv_scrub_time', function(n, v) {
- var now = Date.now();
- if (v + 24 * 60 * 60 * 1000 > now)
- return;
-
- var tr = db.transaction(store, 'readwrite');
- var os = tr.objectStore(store);
- os.index('lvt')
- .openCursor(IDBKeyRange.upperBound(now - 60 * 24 * 60 * 60 * 1000))
- .onsuccess = function(e) {
- var c = e.target.result;
- if (c) {
- os.delete(c.primaryKey);
- c.continue();
- } else {
- settings.set('lv_scrub_time', now);
- }
- };
- });
- };
- }
-
- return {
- /* Record a visit to thread_id, on page last_viewed_page, with up to
- * last_post_nr (of id last_post_id) visible. Should be called on every
- * (thread) pageview.
- */
- set: function(thread_id, last_viewed_page, last_post_nr, last_post_id) {
- cmds.push(new SetCmd({id: thread_id, lvp: last_viewed_page,
- lpn: last_post_nr, lp: last_post_id}));
- run_cmds();
- },
-
- // Call func with the view history of thread_id (and pass extra as well)
- get: function(thread_id, func, extra) {
- cmds.push(new GetCmd({id: thread_id, f: func, e: extra}));
- run_cmds();
- },
-
- update: open_db,
- };
- })();
- // Generic settings menu
- var settings_menu = (function() {
- function mangle_opts(opts) {
- var ret = '';
- for (var k in opts)
- ret = ret + '<option value="' + k + '">' + opts[k].name + '</option>';
- return ret;
- }
-
- var watch_disable = handlers.generic({ setting: function(n, v) {
- this.elm.disabled = v ^ this.extra;
- }});
-
- var select = handlers.generic({
- onchange: function() { settings.set(this.data, this.elm.value); },
- setting: function(n, v) { this.elm.value = v; }
- });
-
- return {
- /* Attach a settings menu to elm. Menus is a list of submenus, in the form
- * [ { title: 'str' | undefined, vars: [ "name" ] } ]
- */
- register: function(elm, menus) {
- var s = settings.all();
- var d = document.createElement('div');
- var html = '';
- var vs = [];
- for (var i = 0; i < menus.length; i++) {
- var menu = menus[i];
- if (i !== 0)
- html += '<hr></hr>';
- if (menu.title !== undefined)
- html += '<b>' + menu.title + '</b>';
- for (var j = 0; j < menu.vars.length; j++) {
- var v = menu.vars[j];
- vs.push(v);
- var sv = s[v];
- if (sv.opt !== undefined) {
- html += '<div><select style="margin-left: 21px">' +
- mangle_opts(sv.opt) + '</select></div>';
- } else {
- html += '<div><input type="checkbox" id="ilcb_' + v + '"></input>' +
- '<label for="ilcb_' + v + '">' + sv.desc + '</label></div>';
- }
- }
- }
- d.innerHTML = html;
- var e = d.firstElementChild;
- var depre = /(!)?(.*)/;
- function h(e, v) {
- var sv = s[v];
- if (sv.opt !== undefined)
- select(e, v);
- else
- handlers.checkbox(e, v);
- var d = sv.dep;
- if (d) {
- var ds = sv.dep.match(depre);
- var i = !ds[1];
- d = ds[2];
- watch_disable(e, d, i);
- }
- }
- while (e !== null) {
- if (e.tagName === 'DIV')
- h(e.firstElementChild, vs.shift());
- e = e.nextElementSibling;
- }
- elm.appendChild(d);
- }
- };
- })();
- // Display a nice menu for managing the ignorelist
- var manage_menu = (function() {
- var menu_list;
- var menu_elms = [];
- var template = document.createElement('tr');
- template.innerHTML =
- '<td></td><td align="right"><a class="itmremove"></a></td>';
-
- function create_elm(user) {
- var tr = template.cloneNode(true);
- tr.firstElementChild.innerHTML = user;
- var a = tr.lastElementChild.firstElementChild;
- a.href = 'javascript:void(0)';
- handlers.ignore_toggle(a, user);
- if (this.appendChild)
- this.appendChild(tr);
- return { user: user.toLowerCase(), elm: tr };
- }
-
- function lc_comp(a, b) {
- return a.toLowerCase().localeCompare(b.toLowerCase());
- }
-
- function update(user, state) {
- if (menu_list === undefined)
- return;
- if (user instanceof Array) {
- var frag = document.createDocumentFragment();
- menu_elms = user.sort(lc_comp).map(create_elm, frag);
- menu_list.appendChild(frag);
- } else {
- var lc = user.toLowerCase();
- var idx;
- if (state) {
- for (idx = 0; idx < menu_elms.length; idx++) {
- if (menu_elms[idx].user.localeCompare(lc) >= 0)
- break;
- }
- var elm = create_elm.call(0, user);
- menu_elms.splice(idx, 0, elm);
- if (idx + 1 < menu_elms.length) {
- menu_list.insertBefore(menu_elms[idx].elm, menu_elms[idx + 1].elm);
- } else {
- menu_list.appendChild(menu_elms[idx].elm);
- }
- } else {
- for (idx = 0; idx < menu_elms.length; idx++) {
- if (menu_elms[idx].user.localeCompare(lc) >= 0)
- break;
- }
- if (idx < menu_elms.length) {
- menu_elms[idx].elm.remove();
- menu_elms.splice(idx, 1);
- }
- }
- }
- }
-
- var addbox_enter = handlers.generic({
- onkeydown: function(k) {
- if (k.which !== 13)
- return true;
-
- k.stopPropagation();
- k.preventDefault();
-
- ignore_list.set(strip_tags(this.elm.value), true);
- this.elm.value = '';
-
- return false;
- }
- });
-
- var addbox_click = handlers.generic({
- onclick: function() {
- ignore_list.set(strip_tags(this.data.value), true);
- this.data.value = '';
- }
- });
-
-
- return {
- // Attach management elements to elm
- register: function(elm) {
- var tbl = document.createElement('table');
- tbl.className = 'itmanage';
- tbl.innerHTML = '<tbody><tr><td colspan="2">' +
- '<input type="text" placeholder="Add user..." width="auto">' +
- '</input> <div class="il_addbtn">Add</div></td></tr></tbody>';
- menu_list = tbl.firstElementChild;
-
- var td = menu_list.firstElementChild.firstElementChild;
- addbox_enter(td.firstElementChild);
- addbox_click(td.lastElementChild, td.firstElementChild);
-
- ignore_list.watch('late', update);
- elm.appendChild(tbl);
- },
- };
- })();
- // Where are we?
- // In the interest of sanity, ftl.thread is true for all thread-like pages
- // (i.e. any page with one or more posts); ftl.threadlist is true for all
- // threadlist-like pages (i.e. any page with a list of threads). The
- // formatting for all such pages is similar enough to treat them equivalently.
- var ftl = {
- // Mobile pages
- mobile: '^https?://m\\.',
- // All forum pages
- forums: '^https?://(m|www)\\.fasttech\\.com/forums',
- // Thread-like pages (i.e. those with posts)
- thread: '^https?://(m|www)\\.fasttech\\.com/forums/[^/]+/t/[0-9]+/.',
- // Permalink pages
- perma: '^https?://(m|www)\\.fasttech\\.com/forums' +
- '/[^/]+/t/[0-9]+/[^/]+\\?[0-9]+$',
- // Threadlist-like pages (i.e. those with thread links)
- threadlist: '^https?://(m|www)\\.fasttech\\.com/forums' +
- '(/[^/]+(/page/[0-9]+)?(/search\\?.*)?)?$',
- // Lists of threads for a single author
- author: '^https?://(m|www)\\.fasttech\\.com/forums/author/',
- // Lists of threads for a single product
- product: '^https?://(m|www)\\.fasttech\\.com/p(roducts?)?/',
- // New thread page for a product
- pnthread: '^https?://(m|www)\\.fasttech\\.com/forums/[0-9]+/post',
- // Forum settings page
- settings: '^https?://www\\.fasttech\\.com/forums/settings$',
- // New arrivals pages
- new_arrivals: '^https?://(m|www)\\.fasttech\\.com/category/1/new-products',
- // Review pages
- reviews: '^https?://(m|www)\\.fasttech\\.com/reviews',
- // Product search
- prsearch: '^https?://(m|www)\\.fasttech\\.com/search',
- // Product category
- prcategory: '^https?://(m|www)\\.fasttech\\.com/c(ategory)?(/|$)',
- };
- for (var k in ftl)
- ftl[k] = new RegExp(ftl[k]).test(location.href);
- // ftl.editor matches all pages with a post editor
- ftl.editor = ftl.thread ||
- (ftl.threadlist && !ftl.settings && !ftl.author) ||
- ftl.pnthread;
- // ftl.threadlist matches all pages listing threads
- ftl.threadlist = ftl.threadlist || ftl.author || ftl.product || ftl.settings;
- // ftl.forums matches all pages with forum elements (threads or posts)
- ftl.forums = ftl.forums || ftl.product;
- // ftl.reviews matches all pages with reviews
- ftl.reviews = ftl.reviews || ftl.product;
-
- if (ftl.thread || ftl.settings) {
- // Menu configuration
- var full_menus = [
- { title: 'Browsing', vars: ['use_theme', 'theme_name', 'track_viewed',
- 'track_posts', 'always_unread', 'hide_threads'] },
- { title: 'Posting', vars: ['quote_quotes', 'quote_imgs'] },
- { title: 'Thread Menu', vars: ['inthread_menu', 'inthread_manage'] },
- { title: 'Post Hiding', vars: ['placeholders', 'hide_ignored',
- 'hide_quotes', 'hide_deleted'] },
- ];
- var thread_menu;
- if (true) {
- thread_menu = [
- { title: 'General', vars: ['use_theme', 'quote_quotes', 'quote_imgs'] },
- { title: 'Post Hiding',
- vars: ['hide_ignored', 'hide_quotes', 'hide_deleted'] },
- ];
- } else {
- thread_menu = full_menus;
- }
-
- settings.register('inthread_menu', 'Show menu in thread toolbar', true, null);
- settings.register('inthread_manage', 'Manage ignored users from the menu',
- false, 'inthread_menu');
- settings.register('placeholders', 'Show placeholders for hidden posts', true,
- null);
- settings.register('hide_quotes', 'Hide posts quoting ignored users', false,
- 'hide_ignored');
- settings.register('hide_deleted', 'Hide deleted posts', true, null);
- settings.register('quote_quotes', 'Include quotes in quotes', true, null);
- settings.register('quote_imgs', 'Include images in quotes', true, null);
- }
- if (ftl.threadlist) {
- settings.register('track_viewed', 'Link to last viewed page', false, null);
- settings.register('track_posts', 'Link to unread posts', true, null);
- settings.register('always_unread', 'Always show unread posts button', false,
- 'track_posts');
- settings.register('hide_threads', 'Hide threads by ignored users', false,
- null);
- }
- if (ftl.editor) {
- settings.register('agree_tou', null, false, null);
- }
-
- block.block('ready');
- if (ftl.forums) {
- var ignore_list = create_ignore_list('ignorelist');
- last_viewed.update();
- if (ftl.thread || ftl.reviews)
- user_tags.update();
- block.block('late');
- block.watch('ready', function() {
- setTimeout(function() { block.unblock('late'); }, 0);
- });
- } else if (ftl.new_arrivals) {
- var ignore_categories = create_ignore_list('ignored_categories');
- } else if (ftl.reviews) {
- user_tags.update();
- }
-
- settings.update();
-
- if (document.readyState === 'loading') {
- document.addEventListener('readystatechange', function() {
- if (document.readyState === 'interactive') block.unblock('ready');
- });
- } else {
- block.unblock('ready');
- }
-
- /* Fix up display of certain post elements:
- * - Fix align tags (which should have been 100% divs to begin with)
- * - Avoid breaking SKU links across lines
- */
- var style = document.createElement('style');
- style.innerHTML =
- '.PostContent span[style*="text-align:"] {display:block;width:100%}\n' +
- 'a.SKUAutoLink {display: inline-block}\n' +
- '.PopoutPanel>ul {margin: -5px -20px 0px -50px!important}\n' +
- '.PopoutPanel>p {margin: 0px!important}\n' +
- '.Badges {cursor:pointer}\n' +
- '.itmanage tbody tr td {padding:0px}\n' +
- '.itmanage .itmremove {padding-left: 16px; height: 16px; background: ' +
- 'url(https://www.fasttech.com/images/minus-button.png) no-repeat}';
- document.head.appendChild(style);
-
- // RE to pull a thread id from a URL
- if (ftl.forums)
- var thread_id_re = new RegExp('/forums/[^/]+/t/([0-9]+)/[^?]*$');
-
- if (ftl.thread) {
- // Add a filter for posts quoting ignored users
- post_filter.filter((function() {
- var quote_res = [];
- function new_qre(user) {
- quote_res.push(
- new RegExp('\\b' + user + ' wrote(</a>)?:?[\\r\\n]*<br>', 'i'));
- }
-
- function update(user, state, idx) {
- if (user instanceof Array) {
- quote_res = [];
- for (var i = 0; i < user.length; i++)
- new_qre(user[i]);
- } else {
- if (state)
- new_qre(user);
- else
- quote_res.splice(idx, 1);
- }
- }
- ignore_list.watch('early', update);
- settings.watch('hide_quotes', post_filter.update);
-
- return function(post) {
- if (settings.get('hide_ignored') && settings.get('hide_quotes')) {
- for (var i = 0; i < quote_res.length; i++) {
- if (quote_res[i].test(post.content_elm.innerHTML))
- return true;
- }
- }
- };
- })());
-
- // Add a filter for posts that the admins have deleted
- post_filter.filter((function() {
- var deleted_re = /post deleted/i;
- var edited_re = /^[ \r\n]*$/;
- settings.watch('hide_deleted', post_filter.update);
-
- return function(post) {
- if (settings.get('hide_deleted')) {
- var wb = post.content_elm.getElementsByClassName('WarningBox')[0];
- if ((wb !== undefined && deleted_re.test(wb.innerHTML)) ||
- edited_re.test(post.content_elm.innerHTML))
- return true;
- }
- };
- })());
-
- // Get all post bodies, desktop and mobile
- var posts;
- block.watch('ready', function() {
- posts = [];
- var elms = document.getElementsByClassName('PostContent');
- for (var i = 0; i < elms.length; i++) {
- var pc = elms[i];
- var user = pc.getAttribute('data-username');
- if (user !== null)
- posts.push({ user: user, content_elm: pc });
- }
- });
-
- // Create a function to create placeholders as needed
- var gen_watch_filter = function(ph_func) {
- return function(post, state) {
- var placeholders = settings.get('placeholders');
- if (state && placeholders) {
- if (!post.placeholder)
- post.placeholder = ph_func(post);
- post.placeholder.style.display = '';
- } else {
- if (post.placeholder !== undefined)
- post.placeholder.style.display = 'none';
- }
- }
- };
-
- // Get this thread's ID
- var thread_id = location.href.match(thread_id_re);
- if (thread_id !== null && thread_id[1] !== undefined)
- thread_id = parseInt(thread_id[1]);
- else
- thread_id = undefined;
- }
-
- // Get the current and last pages from a pager element, desktop and mobile
- function parse_pager(elm) {
- var cur, last, sel;
- if (elm === undefined || elm === null) {
- cur = last = 1;
- } else if (!ftl.mobile) {
- sel = elm.getElementsByClassName('PageLink_Selected')[0];
- if (sel !== undefined)
- cur = parseInt(sel.innerHTML);
- last = parseInt(elm.lastElementChild.previousElementSibling.innerHTML);
- } else {
- sel = elm.getElementsByClassName('active')[0];
- if (sel !== undefined)
- cur = parseInt(sel.firstElementChild.innerHTML);
- last = parseInt(elm.lastElementChild.firstElementChild.innerHTML);
- }
- return {
- cur: cur,
- last: last
- };
- }
-
- if (!ftl.mobile) {
- /* Jump-to-page boxes are broken site-wide. Fix them.
- * The existing JumpToPage box could be fixed by changing "function (e)" to
- * "function (event)" in the event listener, but instead, I'm doing all this.
- */
- var fix_jtp = function() {
- var jtps = document.getElementsByClassName('JumpToBox');
- if (jtps.length === 0)
- return;
-
- var lastpg = parse_pager(jtps[0].parentElement).last;
- function handle_kp(k) {
- if (k.which === 13) {
- k.preventDefault();
- k.stopPropagation();
- var pg = parseInt(this.value);
- if (pg > 0 && pg <= lastpg)
- location.href = base[1] + pg + base[2];
- }
- return false;
- }
-
- for (var i = 0; i < jtps.length; i++) {
- var jtpbox = jtps[i];
- var as = jtpbox.parentElement.getElementsByTagName('a');
- if (as[0] !== undefined) {
- var base = as[0].href.match(new RegExp('(.*/)[0-9]+($|[?#/].*)'));
- if (base !== null)
- jtpbox.addEventListener('keypress', handle_kp);
- }
- }
- };
- block.watch(ftl.forums ? 'late' : 'ready', fix_jtp);
- }
-
- if (ftl.threadlist) {
- // Translate a post number into a page number, handling FT's off-by-one quirk
- var postnr_to_pagenr = function(post, maxpage) {
- return Math.floor(Math.min(maxpage, post / 10 + 1));
- };
-
- // Create a link to a specific page of a thread
- var gen_page_link = function(base, page, hash) {
- var ret = base;
- if (page !== 1)
- ret += '/' + page;
- if (hash)
- ret += '#' + hash;
- return ret;
- };
- }
-
- if (!ftl.mobile) {
- // Re-implement FT's PopoutMenu, only nicer
- var PM2 = (function() {
- var active, timeout;
-
- function show() {
- var p = active.par;
- var c = active.ch;
- p.className += ' focused';
- c.style.left = c.style.top = '0px';
- c.style.display = 'inline';
- var ppb = p.parentElement.getBoundingClientRect();
- var pb = p.getBoundingClientRect();
- var cb = c.getBoundingClientRect();
- c.style.left = Math.min(pb.left - cb.left,
- document.body.clientWidth - cb.width) + 'px';
- c.style.top = (ppb.bottom - cb.top) + 'px';
- }
-
- function hide() {
- if (active === undefined)
- return;
- active.par.className = active.cname;
- active.ch.style.display = 'none';
- active = undefined;
- }
-
- function min(pm) {
- clearTimeout(timeout);
- if (pm !== active)
- hide();
- active = pm;
- show();
- }
-
- function mout() { timeout = setTimeout(hide, 300); }
-
- function add_listeners(elem, pm) {
- elem.addEventListener('mouseover', min.bind(null, pm));
- elem.addEventListener('mouseout', mout);
- }
-
- /* Hack: we can't remove anonymous event listeners, so duplicate elements.
- * We hide the existing element to serve as a decoy for the original
- * PopoutMenu in case it hasn't run yet, then steal all its children.
- */
- function dupe(id) {
- var elm = document.getElementById(id);
- var nelm = elm.cloneNode(false);
- elm.style.display = 'none';
- while (elm.childNodes[0])
- nelm.appendChild(elm.childNodes[0]);
- if (elm.nextElementSibling)
- elm.parentElement.insertBefore(nelm, elm.nextElementSibling);
- else
- elm.parentElement.appendChild(nelm);
- return nelm;
- }
-
- var def = {dupe: true};
- return function(pm) {
- for (var k in def) {
- if (!(k in pm))
- pm[k] = def[k];
- }
- try {
- if (pm.dupe) {
- pm.ch = dupe(pm.ch || (pm.par.replace('Button', '') + 'Popout'));
- pm.par = dupe(pm.par);
- } else {
- pm.ch = document.getElementById(
- pm.ch || (pm.par.replace('Button', '') + 'Popout'));
- pm.par = document.getElementById(pm.par);
- }
- pm.cname = pm.par.className;
- pm.ch.style.padding = '20px';
- add_listeners(pm.par, pm);
- add_listeners(pm.ch, pm);
- } catch (e) {}
- };
- })();
-
- block.watch('ready', function() {
- ['Cart', 'Support', 'Community', 'Account']
- .forEach(function(n) { PM2({par: n + 'Button'}); });
- if (ftl.thread) {
- ['RateThread', 'ForumTools']
- .forEach(function(n) { PM2({par: n}); });
- }
- });
- }
- styles.register('nightmode', undefined,
- '#SearchKeywords,#images ol,#searchBarCategory,button.close{background:0 ' +
- '0!important}#images ol{border:0!important}.btn.active,li.active>a{backgr' +
- 'ound:#0d7bad!important}.FormButton.green{background:#20944b!important}#P' +
- 'roductDetails,#RightPanel,#categoryButton,#container .list-group li a,#f' +
- 'ooter,#searchBarOptionsCell,#searchBoxCell,#searchButtonCell,.AFEntry,.A' +
- 'ttachments,.BGShadow,.BGShadowLight,.OrdersShipmentHeading,.PageNavigati' +
- 'onalPanel,.ProductBackdrop,.ProductFilters,.ProductsGrid,.TicketResponse' +
- ',.TicketResponseFrame,.alert-info,.jumbotron,.list-group li,.mbbc-popups' +
- ' li,.mbbc-popups ul,.ui-dialog,body,td.Pros,ul.nav a{background:#222!imp' +
- 'ortant}.FormButton.blue{background:#3182b9!important}#AccountButton.focu' +
- 'sed,#LeftPanel,#UpdateWarningMsg,#container li a,#container li.active a.' +
- 'dropdown-toggle,#container ol,#navbar>tbody>tr:first-child,.CardShadow,.' +
- 'ControlArrows,.FilterEntry:hover,.FormButton.white,.ForumHeader,.ForumLi' +
- 'nk:hover,.GridItem,.PopoutPanel,.ProductGridItem,.ProductPanelBackdrop,.' +
- 'ReviewContent,.Steps>div,.btn,.dropdown-menu,.dropit-submenu>li,.mbbc-po' +
- 'pups li:hover,.navbarsearch,.panel-body,.panel-heading,.panel-title,.tab' +
- 'le,.table td,.tabs-min,button,div.well,input:not([valbbcode]),select,tex' +
- 'tarea,ul.dropdown-menu>li>a{background:#333!important}.FilterSelected,.F' +
- 'orumLink.Selected,.PageLink:hover,.StaticPageLink_Selected,.divider,.dro' +
- 'p-hover>a,.dropit-submenu,.subCategories li:hover,hr{background:#444!imp' +
- 'ortant}.FormButton.purple{background:#6a3b7f!important}.FormButton.red{b' +
- 'ackground:#9e1531!important}.FormButton.orange{background:#c4571d!import' +
- 'ant}.topLevelCategories li.focused{background-image:url(data:image/png;b' +
- 'ase64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAZklEQVR4AWPwySwkG1' +
- 'NPs2TjRjuyNUs0brwl0bRxj3jzei2yNEs2bfwPwkBD+sTb1wuQrhlhwCvJ5o25ZGhGYJA4KD' +
- 'zI0YwwpGF9LMmaQYEIsplkP0s0b4wnO7TpE88gTXRN22RjAIeVNYXGl+mUAAAAAElFTkSuQm' +
- 'CC)!important;background-position:right 2px!important;background-repeat:' +
- 'no-repeat!important}.mbbc-buttons li{background-image:url(data:image/png' +
- ';base64,iVBORw0KGgoAAAANSUhEUgAAAGwAAACVCAMAAACKJe8uAAAAjVBMVEVMaXG0UlJg' +
- 'YmS+kI/MzMzMzMzMzMzMzMzAxLuoqKiamppWV1cuLi7MzMzMzMzAx8qNjo5FRUaoRkZ8fH1N' +
- 'Tk/MzMzMzMyUPz55OjfMzMzMzMzMzMzMzMzMzMxWeJzJbgbGpxKCoqY8YIC5uqhzqsmwlV99' +
- 'pIB1lTxlghlvfMlxYbKnRy1sk7skfGsNbDRy3rXhAAAAHnRSTlMA/////42hdf//////s8L/' +
- '///////W6///NiMRW0Sx+uQWAAAC5klEQVR4AezSRZLAMAxEUY3SQTkM8v0vOhxG7fNdXr9A' +
- '09vbqo9VZIuZTVaARcGshVEUhfGNlaSZWDDAwWFsxgggylFcWSWzVGLD0lOMgKv3YqLagjVA' +
- '61rnHH4OGguWsnxjnQn7ZY6xEP0FxmXdjZYFcz93i/XDzS+rK5NFzXqNTz8jM39bTkwWabNK' +
- 'N1gBnGz+2yJr2gD4YXCI5cChxVzVzo6NzDE2IDq0SMbNm7HfgwBYYBHQR31xsnkiqToz5hvF' +
- 'yCkaTw/ijEVau0VeFQr8Xqg+wkiqcfNGzOsi/wyjrvtip761hllBKAzvArGSTtcS8P5v8/x+' +
- 'OceRk3iaPd07+QetXXsGKaX0bzQLl4kolRRhWBBnVIRRmghTB+III4yRI4yTIUzriKKV+kKk' +
- 'lFJKiZ7ABZyZF6CFi+JSzlyX45lCjm3Y+1eGH6jNsMaLmJNiE1yr745/JXbBM+tigAVdWaWx' +
- 'Sz+4MvyADxJFyJWtPxpRnW/G+MNnhu/ixsyNRsFTk/whdqVdQSU8Jw27tS5+Zl13seE561IL' +
- 'Oy4mUpzF8JIuu/7faLCl+BvJI0dKKaUvMbe7xXHOhm3tPax2u13BcZXmw56m1LAZMY5jcmyF' +
- 'Fr7F1jOGLxikD/sti55Z+AIivVuLiPVeFHa7h28jbXy3DWcJbQ971twNuduGw6aMog+bUkop' +
- 'fYPI7U43Xcdj2LTVWbqExHQ4UKmExDoDKDQjYnUYgDYQERsMwAZHxBY5ACaPiFWagHeyiJhT' +
- 'sVpF1HHYEKDTcPRR8V8jzw4OG3IPKaX/vb/aqQcchmIAAMPzmjzGC2rz/rebbfvvAb7637eX' +
- 'rdfYCq13DwxjnBFCMkrpLtYBoJrVYQ/HOCFUTKuegGEphNL0XtjRMwO1ENQYfS/MWps55zLv' +
- '/S5WjTdQG2PUV2JCmSedmZo0oEqBu2AhhCzGmKWUdjFu9CzDn4EtegIGxj/IeIzrPP7MqlVj' +
- '7LEhtuoWbAQUelFEFIeMmgAAAABJRU5ErkJggg==)!important;border-radius:5px!im' +
- 'portant}.HourGlass{background:inherit!important}.Stars{background:url(da' +
- 'ta:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAAXVBM' +
- 'VEVMaXH/rVz/s2f/jCv/uGz/vXD+iSf+jSz+kjD+xH3+iiX+jCr+s2P/uG/+wXf+iif+m0T+' +
- 'n0f+pE7+p1L+v3X+wHj+wn3/kjP/mD3/oEj/p1P/tGX/vnT/iCX/xX3uTskzAAAAF3RSTlMA' +
- '/grK/i3p1yHXJX7WA3aZbPXD7o2sP+NiEhsAAABkSURBVHgBZcvFAcMwEEXBL2aFzXb/ZUYY' +
- 'fLdZQI0GfHaPnxo2Lt6iZls9bRDRbHwl17NGgjmOrGWeRmWBx1aVeEJ69GtSXrLyLkjdSY3S' +
- 'rWhUqF3mKWmXjQmM7Z1BOQ1Yx/DXE5S8Bqiv9nzRAAAAAElFTkSuQmCC)!important}.Gra' +
- 'yStars{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4A' +
- 'AAAOCAYAAAAfSC3RAAAA4UlEQVR4AWLwySzEinfu3MkGwrjkcWo8efJk76lTp8pI0njmzBn7' +
- 'Y8eO/T948OB/IG2AXyPCJl5AZ3RthjAARAF4F0omZBWquKfBrcPdOmyEMELk8XFxL+L5T0+n' +
- '04fgbDa7p5UcBk2Utt1u74fDwSE4nU6dwWCwkGW5JYpiw4coBRnwM444wtHtdh3TNB1FURye' +
- '558I8NNeJpNAGgpDjuPaMH5fKBEgDwmCsKd+Iz0SSEEo0UKJqVMdjUZfAmFEvWWuIwzCiGXZ' +
- 'fEiA+sEB9IdWKkTTiBrfF+7xDkHisNbhAqOEltIAVAofAAAAAElFTkSuQmCC)!important}' +
- '.FilterEntry.FilterCancellable{background:url(data:image/png;base64,iVBO' +
- 'Rw0KGgoAAAANSUhEUgAAAAwAAAALCAYAAABLcGxfAAAASklEQVR4AWPwySxkuCUk9J8QBqkD' +
- 'YbBiYjGKBigAs3GJMTAwNDBgUYDOxtSAoQmhmCwNlDmJTE8TxggNiIgjrBimAYxBHEIYpA4A' +
- 'F8kQ7Ga9snUAAAAASUVORK5CYII=) 10px 3px no-repeat,#444!important;border-c' +
- 'olor:#0d7bad!important;box-shadow:0 2px 2px #111!important}input[src="/i' +
- 'mages/errorreport.png"]{background:url(data:image/png;base64,iVBORw0KGgo' +
- 'AAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAMFBMVEX////////////////////////////' +
- '///////////////////////////////////9Or7hAAAAAEHRSTlMBCBIcJS45RlVkcYOVqbz' +
- 'NHir32QAAAGNJREFUeAEUTAkBBEEIUhMIDeAazPbvdjgvn0xVAXkCGocCwKcNaH4/9Sn08ym' +
- 'Qae00DUBRAtbGIHJUDc1Y1DRuKRY25Y3/gOa8BwKQFe/ugcAHpnfv7p49e/bcPab/Z8HgPgC' +
- 'LAx2nigq2jAAAAABJRU5ErkJggg==)!important}.CellMode .GridItemPrice{backgr' +
- 'ound:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHUAAAAeCAYAAAASN' +
- '1ElAAAAi0lEQVR4Ae3aSRXDIABAwZiIjgrAQkV0X46VUT1RFAOV0M3Gf3MYBR8IEKbXfvMhZ' +
- 'RG1Z4jasm7vj6kVlUswqlnaisqlFZX1Z25F5fmP2YrKHIxqlraiMovasvwjtqIyglHN0lZUR' +
- 'iAqolp+sVHqcKTB5QOuCXGhj19vfpLjOQsenuGJKB5zM0TtWb7rxpkaVlv9JQAAAABJRU5Er' +
- 'kJggg==) no-repeat!important;width:134px!important}.ForumHeader input[ty' +
- 'pe=image]{border:0!important;vertical-align:text-top!important}#AddedToC' +
- 'artPopupPanel,#container ol,.CardShadow,.ForumThread,.GridItem,.ProductG' +
- 'ridItem,.ProductPanelBackdrop,.TicketResponseFrame,.dropit-submenu,.mbbc' +
- '-buttons li,.panel-body,.panel-heading,td.Pros{border:1px solid #444!imp' +
- 'ortant}#searchBarOptionsCell,#searchBoxCell,#searchButtonCell,.ForumThre' +
- 'ad tr td,.navbarsearch{border-bottom:1px solid #444!important}#Ignorelis' +
- 'tPopout tr td,.PostFlags ul li{border-bottom:none!important}.FilterEntry' +
- ':hover,.FilterSelected,.StaticPageLink_Selected{border-color:#0d7bad!imp' +
- 'ortant}#categoryButton,#container li a,#container ul,.ControlArrows,.For' +
- 'umQuote,.ForumsNavigation,.PageLink,.PageNavigationalPanel,.PostFlags,.S' +
- 'KUAutoLink,.Signature,.TightInformationBox,.list-group li,.mbbc-popups u' +
- 'l,body .FormButton[class],div,hr,td{border-color:#444!important}.btn,but' +
- 'ton,input:not([valbbcode]),select,textarea{border-color:#444!important;b' +
- 'order-style:solid!important}#searchBarOptionsCell{border-left:1px solid ' +
- '#444!important}.ForumQuote{border-left:5px solid #0d7bad!important}.drop' +
- 'it-submenu>li,blockquote{border:none!important}#searchButtonCell{border-' +
- 'right:1px solid #444!important}.ForumLink.Selected,.ForumLink:hover{bord' +
- 'er-right:3px solid #0d7bad!important}#searchBarOptionsCell,#searchBoxCel' +
- 'l,#searchButtonCell{border-top:1px solid #444!important}#LeftPanel,.Popo' +
- 'utPanel{box-shadow:0 15px 30px #111!important}.ProductGridItem{box-shado' +
- 'w:0 3px 3px #111!important}.BGShadow,.BGShadowLight,.CardShadow,.FilterS' +
- 'elected,.ForumLink.Selected,.GridItem,.StaticPageLink_Selected,.subCateg' +
- 'ories li:hover{box-shadow:none!important}.SysMsgBanner{color:#000!import' +
- 'ant}#AccountButton a{color:#0d7bad!important}#StaticPageContent [style],' +
- '#categoryButton a,#content_ProductName,#footer,.AFTitle,.ControlArrows a' +
- ',.FieldLabel,.FlagValue,.Gray,.GrayText,.GridItemDesc>div,.GridItemModel' +
- 's,.Name>a,.NewList,.PageLink,.Pager,.btn,.dropit a,.navmenubutton a,.pan' +
- 'el-default>.panel-heading,.panel-title,.subCategories a,.topLevelCategor' +
- 'ies a,a.SortOrder,body,button,input:not([valbbcode]),select,textarea,ul.' +
- 'dropdown-menu>li>a{color:#bbb!important}.mbbc-popups li{color:#ccc!impor' +
- 'tant}.btn.active,body .FormButton[class],ul.dropdown-menu>li>a:hover{col' +
- 'or:#fff!important}.GridItemPackSize{display:inline!important;float:none!' +
- 'important;margin:0 0 0 -22px!important;vertical-align:sub!important}#DMC' +
- 'A,.logo,.navseals,a[href$="/faq/money-back-guarantee"]>img{display:none!' +
- 'important}#categoryButton{margin:0 20px!important}#footer,.PageContentPa' +
- 'nel>div:last-child[style]{margin:0!important}#CartPopupClose{margin:-10p' +
- 'x -20px!important}.mbbc-row1{margin-bottom:1px!important}.ForumLink:hove' +
- 'r{margin-right:-3px!important}#Tab{margin-top:10px!important}#AddedToCar' +
- 'tPopupPanel{padding:0 10px!important;position:fixed!important;right:40px' +
- '!important;top:40px!important}.menubuttons{padding:0 20px!important}#Ans' +
- 'wer{padding:0!important}#searchbar{padding-right:20px!important}#AddedTo' +
- 'CartPopupPanel,#categoryButton{width:auto!important}');
-
- styles.register('darkft', undefined,
- '.FieldFlag,.Pager .PageLink{font-size:9pt!important}.Pager .PageLink:hov' +
- 'er{background:#111!important;color:#fefefe!important}.FieldFlag{backgrou' +
- 'nd:#1980b0!important;font-weight:400!important;padding:3px 5px!important' +
- '}.ForumLink.Selected{background:#222!important;border-right:3px solid #6' +
- '66!important}.ForumHeader,.ForumThread .ThreadCommandBar,.logo,body,div#' +
- 'contents{background:#333!important}.logo{visibility:hidden!important}.Fo' +
- 'rumThread tr td{background:#363636!important}#AccountButton.focused,#Acc' +
- 'ountPopout,#AddedToCartPopupPanel,#CartPopout,#CartPopupPanel,#Community' +
- 'Popout,#LeftPanel,#SupportPopout,#categoryButton,#categoryPopout,#navbar' +
- ',#searchBarOptionsButton,.CellMode .ProductGridItem,.FilterEntry:hover,.' +
- 'FormButton.white,.FormButton.white:hover,.LargeFilterEntry:hover,.LineMo' +
- 'de .ProductGridItem,.ModalDialog,.OrdersShipmentHeading,.PageNavigationP' +
- 'anel,.ProductBackdrop,.ProductFilters,.ProductFilters .FilterCancellable' +
- ',.ProductFilters .FilterSelected,.ProductPanelBackdrop,.mbbc .mbbc-edito' +
- 'r,div#footer,hr,tr{background:#444!important}.HourGlass{background:#444f' +
- 'e5!important}.Cons .FieldFlag,.Pros .FieldFlag{background:#4c9ed9!import' +
- 'ant}#navbar .focused,.BGShadow,.BGShadowLight,.PopoutPanel,.Steps .focus' +
- 'ed{background:#666!important}.PopoutPanel{border-radius:0!important;box-' +
- 'shadow:0 5px 5px #888!important}#searchBarCategory{background:#777!impor' +
- 'tant}.Pager .ControlArrows{background:#888!important;font-weight:400!imp' +
- 'ortant}.Pager .PageLink_Selected{background:#999!important}#ForumPopout,' +
- '#ForumToolsPopout,#RateThreadPopout{background:#fff!important}#CartButto' +
- 'n,#CommunityButton,#SupportButton,#searchBarOptionsCell,#searchButtonCel' +
- 'l,.GridViewIcon,.GroupViewIcon,.ProductGridMenu,.searchbar_focus #search' +
- 'BarOptionsCell,.searchbar_focus #searchButtonCell{background-image:url(d' +
- 'ata:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAAJYBAMAAADh0yLyAAAAJ1B' +
- 'MVEVMaXFqbG11dXX9/f3l5eXd3eBadIdWbnlWc4RYieRmZ2dpaWlsbW2OPQlLAAAADXRSTlM' +
- 'A////////////r0YgYtO1qQAAAq9JREFUeAHt2sd160YYx9FxKgBcekc24ADsHTizVwBakEr' +
- 'g6+CpgBdLcHYJLsA9KTmnZ0PQof+U7j0q4Hc+fMM0KvcAALpI9xsocL2K+/t94GoT6KACNyZ' +
- '4oIF20AQF2kGBdtAEBdpBgXbQBAXaQYF20AQF2kGBdtAEI5UMAAAA4V9oBC43938PV/sO3My' +
- '1FihQoECB+yBQoECBAgUKFChQoECBAgUKFChQoEA3TcsBAAAA9CXbUEuq+pOhpNoO/fVfTZ5' +
- 'ga3Wqn6Y/4hLr3ToM4YFj9gRLHdIDb5VwyTuYPsFh4SExwXeGeh35YQEAAACAf/h1K/8aogq' +
- '8q7rt+74lB/bXhvjAfkwPrAIXHZKaHNj6oUYHXsf1/ZAcONRtn/5O0o/ZgW3rvTjx4xYAAAA' +
- 'ArsIEtjrWlj3BbfojHrbxOziEBw7pE0x/xKfN6+ACday1tpY8wTF7gq2168ZxfHw76CoMAAA' +
- 'AAM4ild+c7xL9PrBLdEiBT1ebQA8hUKBAgQIFChQoUKBAgQIFChQoUKBAgQIFChSYftN0cRE' +
- 'ZmAEAAOBstrJfu7melP3q5hL4J5u54gN3AgUKFChQoECBAgUKFChQoECBAgUKFChQoMCMwN1' +
- 'cjzgQAABgmt6bjqZJoEA8YoF4xHsgMA0AADD9ROBs2EHsoEDs4OEDAADaNH1akm1bbSXZONa' +
- 'jo/CvnUfvlUUcklpryz4ktT2PPiRTe/08+pCMS3/68E7yXvg7yadH4e8kU0l/Jyl3BAAAfPm' +
- 'T70uqzU/eTw9c/5Ae+P0jDRQoUKDArutWJrgwcP3QJ+iQdE5x+ATtoAl6oRYoUOAeCBRYUnU' +
- '/+aqk+vEnBQAAF9qRXGgLFChQoMBlXt9YCbSD/5+zGw7Jwgme28EFuht20Au1QIECBQp0oe1' +
- 'COx0AAFf2ljch8gqLTAAAAABJRU5ErkJggg==)!important}#navbar tr.navbarsearch' +
- ',.navsealsbg,body.stripe{background-image:url(data:image/png;base64,iVBO' +
- 'Rw0KGgoAAAANSUhEUgAAAGQAAABGAQMAAAAASKMqAAAAA1BMVE2.5EQ1TRdOAAAAEElEQVR4' +
- 'AWMYVmAUjIJRAAAD1AABVz/btAAAAABJRU5ErkJggg==)!important}.searchbar_focus' +
- ' #searchBoxCell{background-image:url(data:image/png;base64,iVBORw0KGgoAA' +
- 'AANSUhEUgAAAD0AAAAtBAMAAADvmn5BAAAAD1BMVEWYmJmzs7PBwcHGxsagoaK4fiRWAAAAI' +
- 'ElEQVR4AWNiwA+YBPECgcGuf6DkR+VH5UflR+UpLd8AJUsIkz10gdcAAAAASUVORK5CYII=)' +
- '!important}#searchBoxCell{background-image:url(data:image/png;base64,iVB' +
- 'ORw0KGgoAAAANSUhEUgAAAD0AAAAtAQMAAAAnevExAAAAA1BMVEV3d3dY20ihAAAADUlEQVR' +
- '4AWMYfGAUAAABlQABpWSZFgAAAABJRU5ErkJggg==)!important}.SysMsgBanner{borde' +
- 'r:1px dotted #444!important}#DMCA div.dm-1,#DMCA div.dm-2,#LeftPanel,#ca' +
- 'tegoryButton,#searchBarOptionsButton,.BorderedPanel,.FormButton,.ForumTh' +
- 'read,.ForumThread .Signature,.InformationBox,.Pager .ControlArrows,.Page' +
- 'r .PageLink,.Pager .PageLink_Selected,.ProductThumbnails,.Reviews .Cons,' +
- '.SKUAutoLink,.SingleLineTextBox,.TightInformationBox,.VerticalTextArea,.' +
- 'WarningBox{border:1px solid #444!important}.ForumQuote{border:1px solid ' +
- '#555!important;border-left:5px solid #666!important}.mbbc .mbbc-editor{b' +
- 'order:none!important}td{border-bottom:0!important}#ProductDetails .Attri' +
- 'butesTableRowGroupTitle{border-bottom:1px dashed #444!important}.Discoun' +
- 'tsTable,.ProductDescriptions,.fixedCategoryLink,.scHeading{border-bottom' +
- ':1px dotted #444!important}#navbar,.FilterHeading,.FooterBanner,.PostFla' +
- 'gs ul li,.tabs-min .ui-widget-header{border-bottom:1px solid #444!import' +
- 'ant}.SingleLineTextBox:focus,.VerticalTextArea:focus{border-color:#444!i' +
- 'mportant}.ForumThread .Signature,.Reviews .ReviewContent{border-left:5px' +
- ' solid #444!important}.ForumsNavigation{border-right:0 solid #e0e0e0!imp' +
- 'ortant}#ProductSpecifications,.FooterLeft,.navmenubutton_separator{borde' +
- 'r-right:1px dotted #444!important}.PostFlags,td.PageNavigationalPanel{bo' +
- 'rder-right:1px solid #444!important}.FilterEntry:hover,.LargeFilterEntry' +
- ':hover,.ProductFilters .FilterCancellable,.ProductFilters .FilterSelecte' +
- 'd,.subCategories li:hover,div.StaticPageLink_Selected{border-right:3px s' +
- 'olid #444!important}#navbar .hdivider,.FooterBanner,.OrdersShipmentHeadi' +
- 'ng,.PopoutPanel{border-top:1px solid #444!important}.BGShadow{box-shadow' +
- ':0 1px 1px #666!important}.BGShadowLight{box-shadow:0 3px 3px #666!impor' +
- 'tant}#CartPopout .ViewCart a:hover,#DMCA,#DMCA div.dm-1 a,#DMCA div.dm-2' +
- ' a,#ProductDetailsPanel .Price,#navbar .focused a,#searchButtonCell,.Cel' +
- 'lMode .GridItemPrice,.FieldFlag a,.FormButton,.FormButton.blue:hover,.Fo' +
- 'rmButton.green:hover,.FormButton.orange:hover,.FormButton.purple:hover,.' +
- 'FormButton.red:hover,.LineMode .GridItemPrice,.MemberRankIndex,.Pager .P' +
- 'ageLink_Selected,.Pager .PageLink_Selected:hover,.Pager .PageLink_Select' +
- 'ed:visited,.Steps .focused,.Steps .focused .StepText,.Steps .focused .St' +
- 'epTitle,.tabs-min .ui-state-default a,.unitSelector{color:#444!important' +
- '}.tabs-min .ui-state-active a{color:#666!important}#navbar .menulinks sp' +
- 'an a:active,a,a:visited{color:#d5d5d5!important}#categoryButton,#searchB' +
- 'arCategory,.CartTable .Name a,.CellMode .GridItemModels,.FormButton.whit' +
- 'e,.FormButton.white:hover,.ForumThread .ThreadCommand,.Information,.Line' +
- 'Mode .GridItemModels,.Pager .PageLink,.navmenubutton a,.subCategories a,' +
- '.topLevelCategories a,.topLevelCategories li.focused a{color:#e1e1e1!imp' +
- 'ortant}.Black{color:#e2e2e2!important}.PageTitle{color:#e5e5e5!important' +
- '}#categoryButton a,.PostFlags .FlagValue,.SingleLineTextBox:focus,.Verti' +
- 'calTextArea:focus{color:#f1f1f1!important}body{color:#f3f3f3!important}#' +
- 'content_ProductName,.mbbc .mbbc-align-popup li,.mbbc .mbbc-code-popup li' +
- ',.mbbc .mbbc-editor,.mbbc .mbbc-font-popup li,.mbbc .mbbc-list-popup li,' +
- '.mbbc .mbbc-simple-popup li,.mbbc .mbbc-size-popup li,.subCategories a:h' +
- 'over,.topLevelCategories a:hover,a:hover{color:#fff!important}.MemberRan' +
- 'kUsername{font-weight:700!important}.ForumGroup{padding:3px 10px!importa' +
- 'nt}.mbbc .mbbc-buttons ul{padding:5px 0 3px!important}.mbbc .mbbc-emotic' +
- 'on-popup .mbbc-group li{padding:8px!important}');
-
- settings.register('use_theme', 'Use custom theme', false, null);
- settings.register('theme_name', null, 'nightmode', 'use_theme', {
- nightmode: { name: 'Night mode' },
- darkft: { name: 'Pafapaf\'s DarkFT' },
- });
- styles.update();
- // Add a "Top of page" button at the bottom of the page, aligned with the pager
- if ((ftl.thread && !ftl.perma) || (ftl.threadlist && !ftl.settings)) {
- var add_top_btn;
- if (!ftl.mobile) {
- add_top_btn = function() {
- var elm = document.getElementsByClassName('ForumThread TightTable')[0];
- if (elm)
- elm = elm.nextElementSibling;
- if (!elm)
- return;
- elm.className = 'Pager';
- var tbtn = document.createElement('span');
- tbtn.className = 'ControlArrows';
- tbtn.setAttribute('style', 'float: left; min-width: 150px; ' +
- 'max-width: 250px; text-align: center');
- tbtn.innerHTML = '<a>Top of page</a>';
- tbtn.firstElementChild.href = 'javascript:void(0)';
- handlers.top_click(tbtn);
- var pager = elm.firstElementChild;
- elm.appendChild(tbtn);
- if (pager) {
- var pspan = document.createElement('span');
- pspan.appendChild(pager);
- elm.appendChild(pspan);
- } else {
- elm.parentElement
- .insertBefore(document.createElement('br'), elm.nextElementSibling);
- }
- };
- } else {
- add_top_btn = function() {
- var elm = document.getElementsByClassName('ListRow')[0];
- if (elm)
- elm = elm.parentElement.nextElementSibling;
- if (!elm)
- return;
- var tbtn = document.createElement('button');
- tbtn.className = 'btn btn-default';
- tbtn.innerHTML = 'Top';
- handlers.top_click(tbtn);
- if (elm.firstElementChild) {
- tbtn.style.marginTop = '-5px';
- elm = elm.firstElementChild;
- var td = document.createElement('td');
- td.style.textAlign = 'right';
- td.appendChild(tbtn);
- elm.style.width = '100%';
- elm.firstElementChild.firstElementChild.appendChild(td);
- } else {
- var d = elm.appendChild(document.createElement('div'));
- d.setAttribute('style', 'width: 100%; text-align: right; ' +
- 'margin-bottom: 8px');
- d.appendChild(tbtn);
- }
- };
- }
- block.watch('ready', add_top_btn);
- }
-
- if (ftl.editor) {
- var bbeeditor; // element to scroll to
- var bbetext; // textarea
- var bbeexpand; // expand button (mobile)
- var bbepanel; // parent of editor
- if (!ftl.mobile) {
- var fix_editor = function() {
- if (bbetext === undefined)
- bbetext = document.getElementsByClassName('mbbc-editor')[0];
- if (bbetext !== undefined) {
- // Save & restore the editor text
- if (history.state && history.state.saved_post)
- bbetext.value = history.state.saved_post;
- window.addEventListener('pagehide', function() {
- var state = history.state;
- if (state === null)
- state = {};
- state.saved_post = bbetext.value;
- history.replaceState(state, '');
- });
-
- // Remove the broken size=[67] buttons
- var size_popup = document
- .getElementsByClassName('mbbc-size-popup')[0];
- if (size_popup !== undefined) {
- size_popup.lastElementChild.remove();
- size_popup.lastElementChild.remove();
- }
- // Fix the editor width
- bbetext.style.boxSizing = 'border-box';
- bbetext.style.width = '100%';
- // Add a YouTube button
- var url_btn = document.getElementsByClassName('mbbc-url')[0];
- if (url_btn !== undefined) {
- var yt_btn = document.createElement('li');
- yt_btn.innerHTML = ' ';
- yt_btn.className = 'mbbc-youtube';
- yt_btn.addEventListener('click', function() {
- var sp = bbetext.selectionStart;
- var ep = bbetext.selectionEnd;
- var sel;
- if (ep < sp) {
- sp = ep;
- ep = bbetext.selectionStart;
- }
- if (ep !== sp) {
- sel = bbetext.value.slice(sp, ep);
- } else {
- sel = prompt('Video URL:', '');
- if (sel === null)
- return;
- var vid = sel
- .match(new RegExp('[/?=#]([-\\w]{11})([^-\\w]|$)'));
- if (vid !== null)
- sel = 'https://www.youtube.com/watch?v=' + vid[1];
- }
- if (sel === undefined)
- return;
- bbetext.value = bbetext.value.slice(0, sp) +
- '[youtube]' + sel + '[/youtube]' +
- bbetext.value.slice(ep);
- bbetext.selectionStart = bbetext.selectionEnd = sp + 9 +
- (sel === '' ? 0 : 10 + sel.length);
- bbetext.focus();
- });
- url_btn.parentElement.insertBefore(yt_btn, url_btn);
- }
- }
- };
-
- block.watch('late', function() {
- // Persist the terms of use checkbox
- var toubox = document.getElementById('AgreeTerms');
- if (toubox !== null)
- handlers.checkbox(toubox, 'agree_tou');
-
- bbeeditor = document.getElementById('bbEditor');
- if (bbeeditor !== null) {
- bbetext = bbeeditor.getElementsByClassName('mbbc-editor')[0];
- if (bbetext !== undefined)
- fix_editor();
- else
- new MutationObserver(function(es, mo) {
- mo.disconnect();
- fix_editor();
- }).observe(bbeeditor, { childList: true });
- }
- });
- } else {
- block.watch('ready', function() {
- bbetext = document.getElementById('RawContent');
- if (bbetext !== null) {
- bbepanel = bbetext.parentElement.parentElement.parentElement;
- bbeeditor = bbepanel.parentElement;
- bbeexpand = bbeeditor.previousElementSibling.firstElementChild
- .firstElementChild;
- }
- });
- }
- }
-
- if (ftl.thread && !ftl.perma) {
- // Re-implement quotes in a way that sort of works
- var fix_quote_btns = (function() {
-
- function wrap_tag(tag, val, str) {
- return '[' + tag + (val ? '=' + val : '') + ']' + str + '[/' + tag + ']';
- }
-
- function inner_quote(elm, range, depth) {
- var tmp = '';
- for (var e = elm.firstChild; e !== null; e = e.nextSibling) {
- var sp, ep;
- if (range !== undefined) {
- if (range.startContainer.compareDocumentPosition(e) === 2)
- continue;
- if (range.endContainer.compareDocumentPosition(e) === 4)
- break;
- if (range.startContainer === e)
- sp = range.startOffset;
- if (range.endContainer === e)
- ep = range.endOffset;
- }
- switch (e.tagName) {
- case 'BR':
- tmp += '\n';
- break;
-
- case 'STRONG':
- tmp += wrap_tag('b', '', inner_quote(e, range, depth));
- break;
-
- case 'EM':
- tmp += wrap_tag('i', '', inner_quote(e, range, depth));
- break;
-
- case 'HR':
- tmp += '[hr]';
- break;
-
- case 'P':
- if (e.innerHTML !== '')
- tmp += '\n' + inner_quote(e, range, depth);
- break;
-
- case 'SPAN':
- var y = e.style;
- var t = null;
- var v = '';
- if (y.textDecoration === 'underline') {
- t = 'u';
- } else if (y.textDecoration === 'line-through') {
- t = 'y';
- } else if (y.fontSize !== '') {
- t = 'size';
- v = parseInt(y.fontSize);
- } else if (y.color !== '') {
- t = 'color';
- v = y.color;
- } else if (y.textAlign !== '') {
- t = 'align';
- v = y.textAlign;
- } else {
- console.log('Unknown span!');
- }
-
- tmp += wrap_tag(t, v, inner_quote(e, range, depth));
- break;
-
- case 'DIV':
- if (e.className === 'ForumQuote') {
- if (tmp[tmp.length - 1] !== '\n')
- tmp += '\n';
- if (depth === 0 && settings.get('quote_quotes'))
- tmp += wrap_tag('quote', '',
- inner_quote(e.firstElementChild, range, depth + 1).trim());
- } else {
- console.log('Unknown div!');
- }
-
- break;
-
- case 'IFRAME':
- var m = e.src.match(/youtube[^\/]*.com.*\/embed\/([^?]+)/);
- if (m !== null && m[1] !== undefined) {
- /* A YouTube tag inside a quote breaks the parsing of the quote.
- tmp += wrap_tag('youtube', '',
- 'https://www.youtube.com/watch?v=' + m[1])
- */
- tmp += wrap_tag('url',
- 'https://www.youtube.com/watch?v=' + m[1], 'YouTube video');
- } else {
- console.warn('Unknown iframe!');
- }
- break;
-
- case 'IMG':
- if (settings.get('quote_imgs')) {
- tmp += wrap_tag('img', '', e.src);
- } else if (e.parentElement.tagName !== 'A') {
- tmp += wrap_tag('url', e.src, 'Image');
- } else {
- tmp += 'Image';
- }
- break;
-
- case 'A':
- if (e.className === 'SKUAutoLink') {
- tmp += e.textContent;
- } else {
- var do_quote = true;
- if ((depth > 0 || !settings.get('quote_quotes') &&
- e.innerHTML.match(/\bwrote$/) !== null)) {
- // Is this a permalink for a quote we'll remove?
- var s = e;
- var l;
- do {
- if (s.nextSibling === null) {
- l = (l === undefined) ? s : l;
- s = s.parentElement.nextSibling;
- } else {
- s = s.nextSibling;
- }
-
- /* Between the <a> and the <div>, we only want to see a
- * colon and an unpredictable number of <br> and empty <p>
- * elements. The <div> may be outside the current element.
- */
- if (s.tagName === 'DIV' && s.className === 'ForumQuote') {
- do_quote = false;
- e = (l === undefined) ? s : l;
- break;
- } else if (s.tagName === undefined) {
- if (s.textContent.match(/[^:\r\n]/) !== null)
- break;
- } else if (s.innerHTML !== '' ||
- (s.tagName !== 'P' && s.tagName !== 'BR')) {
- break;
- }
- } while (true);
- }
- if (do_quote)
- tmp += wrap_tag('url', e.href, inner_quote(e, range, depth));
- }
- break;
-
- case undefined:
- // Filter out newlines and empty tags
- tmp += e.wholeText.slice(sp ? sp : 0, ep)
- .replace(/[\r\n]+/mg, '')
- .replace(/\[([^\]=]*)(=[^\]]*)?\]\[\/\1\]/mg, '');
- break;
-
- default:
- console.warn('Unhandled tag ' + e.tagName);
- }
- }
- return tmp;
- }
-
- function quote(user, elm) {
- if (bbetext === null) {
- console.error('bbEditor text box not found!');
- return;
- }
- var post_id;
- var pid = elm.id.match(/^POST([0-9]+)$/);
- if (pid !== null)
- post_id = pid[1];
-
- var sel = getSelection();
- if (sel.rangeCount > 0) {
- sel = sel.getRangeAt(0);
- if (sel.collapsed || !sel.intersectsNode(elm))
- sel = undefined;
- } else {
- sel = undefined;
- }
-
- if (bbetext.value.length > 0 &&
- bbetext.value[bbetext.value.length - 1] !== '\n')
- bbetext.value += '\n';
- if (thread_id !== undefined && post_id !== undefined)
- bbetext.value += wrap_tag('url', '/forums/-/t/' + thread_id + '?' +
- post_id, user + ' wrote') + ':\n';
- else
- bbetext.value += user + ' wrote:\n';
- bbetext.value += wrap_tag('quote', '', inner_quote(elm, sel, 0)
- .trim().replace(/[\r\n]{3,}/mg, '\n\n')) + '\n';
-
- if (bbeeditor)
- bbeeditor.scrollIntoView();
-
- if (bbeexpand && bbepanel && bbepanel.className &&
- !/\bin\b/.test(bbepanel.className))
- bbeexpand.click();
- }
-
- var quote_click = handlers.generic({ onclick: function() {
- quote(this.data.getAttribute('data-username'), this.data);
- }});
-
- return function(elms, func) {
- for (var i = 0; i < elms.length; i++) {
- var elm = elms[i].content_elm;
- quote_click(func(elm), elm);
- }
- };
- })();
-
- if (!ftl.mobile) {
- var replace_quotebtn = function(elm) {
- // Ugh.
- var oldbtn = elm.parentElement.parentElement.parentElement
- .previousElementSibling.firstElementChild.lastElementChild
- .firstElementChild;
- var newbtn = document.createElement('a');
- newbtn.innerHTML = 'quote/reply';
- newbtn.href = 'javascript:void(0)';
- oldbtn.parentElement.insertBefore(newbtn, oldbtn);
- oldbtn.remove();
- return newbtn;
- };
-
- block.watch('late', function() {
- fix_quote_btns(posts, replace_quotebtn);
- });
- } else { // mobile
- var replace_quotebtn_m = function(elm) {
- // Ugh.
- var oldbtn = elm.parentElement.firstElementChild.lastElementChild
- .lastElementChild.firstElementChild;
- var newbtn = document.createElement('a');
- newbtn.innerHTML = oldbtn.innerHTML;
- newbtn.href = 'javascript:void(0)';
- newbtn.tabindex = '-1';
- newbtn.role = 'menuitem';
- oldbtn.parentElement.insertBefore(newbtn, oldbtn);
- oldbtn.remove();
- return newbtn;
- };
-
- block.watch('late', function() {
- fix_quote_btns(posts, replace_quotebtn_m);
-
- // Add a link to forum settings to allow ignorelist management
- // Ugh. There's no semi-robust way to select this.
- var li = document.querySelector('ul.nav:nth-child(1)>li:nth-child(3)' +
- '>ul:nth-child(2)>li:nth-child(8)');
- if (li !== null) {
- var new_li = document.createElement('li');
- new_li.innerHTML = '<a title="Forum Settings" ' +
- 'href="https://www.fasttech.com/forums/settings">' +
- 'Forum Settings</a>';
- li.parentElement.insertBefore(new_li, li);
- }
- });
- }
- }
-
- if (ftl.thread && ftl.mobile) {
- // Fix up YT iframe size: CSS doesn't work well here.
- var fr_resize = (function() {
- var frs;
- var raf;
- function do_resize() {
- for (var i = 0; i < frs.length; i++) {
- var fr = frs[i];
- fr.elm.style.height = Math.ceil(fr.elm.clientWidth * fr.ar) + 'px';
- }
-
- raf = undefined;
- }
- return function(fr) {
- if (frs === undefined) {
- frs = [];
- window.addEventListener('resize', function() {
- if (raf === undefined)
- raf = requestAnimationFrame(do_resize);
- });
- }
- fr.style.maxWidth = fr.width + 'px';
- fr.style.width = '100%';
- frs.push({elm: fr, ar: fr.height / fr.width});
- };
- })();
-
- block.watch('ready', function() {
- var frs = document.getElementsByTagName('iframe');
- for (var i = 0; i < frs.length; i++)
- fr_resize(frs[i]);
- });
- }
- if (ftl.thread && !ftl.perma) {
- var scroll_to_hash = function() {
- function scroll(elm) {
- if (elm) {
- var sd = elm.style.display;
- elm.style.display = '';
- elm.scrollIntoView();
- elm.style.display = sd;
- }
- }
- if (location.hash === '#unread' || location.hash === '#last')
- last_viewed.get(thread_id, function(hash, lvp, lpn, lp) {
- block.watch('filter', function() {
- var i;
- var pid = 'POST' + lp;
- for (i = posts.length - 1; i >= 0; i--) {
- if (posts[i].content_elm.id === pid)
- break;
- }
- if (i < posts.length - 1)
- scroll(posts[i + 1].post_elms[0]);
- else if (hash === '#last')
- scroll(posts[posts.length - 1].post_elms[0]);
- });
- }, location.hash);
- else if (location.hash !== '')
- block.watch('filter', function() {
- scroll(document.getElementById(location.hash));
- });
- // Drop the hash so we won't run again
- history.replaceState(history.state, '', location.pathname);
- };
- }
-
- if (ftl.threadlist) {
- if (!ftl.mobile) {
- var add_last_viewed =
- function(elm, last_viewed_page, last_post_nr, last_post_id) {
- var row = elm.parentElement;
- var pelm = row.parentElement.getElementsByClassName('Pager')[0];
- var p = parse_pager(pelm);
- var skip_margin = false;
-
- if (pelm === undefined) {
- skip_margin = true;
- if (!ftl.settings) {
- pelm = document.createElement('div');
- pelm.className = 'Pager';
- row.appendChild(pelm);
- } else {
- pelm = row.parentElement.appendChild(document.createElement('div'));
- pelm.className = 'Pager';
- }
- }
-
- if (settings.get('track_viewed')) {
- var lv = document.createElement('a');
- lv.href = gen_page_link(elm.href, last_viewed_page);
- lv.innerHTML = 'Last viewed';
- lv.className = 'FormButton blue';
- if (!skip_margin)
- lv.style.marginLeft = '5px';
- pelm.appendChild(lv);
- skip_margin = false;
- }
-
- var tr = row.parentElement.parentElement;
- var ts = tr.getElementsByClassName('ThreadStats')[0];
- var pc;
- if (ts !== undefined)
- pc = (pc = ts.innerHTML.match(/Replies: ([0-9]+)/)) ?
- parseInt(pc[1]) : undefined;
- var unread = pc > 0 && pc >= last_post_nr;
- if ((unread || settings.get('always_unread')) &&
- settings.get('track_posts')) {
- var np = document.createElement('a');
- if (unread) {
- np.innerHTML = 'Unread posts';
- np.className = 'FormButton red';
- np.href = gen_page_link(elm.href,
- postnr_to_pagenr(last_post_nr, p.last), 'unread');
- } else {
- np.innerHTML = 'No unread posts';
- np.className = 'FormButton white';
- np.href = gen_page_link(elm.href,
- postnr_to_pagenr(last_post_nr, p.last), 'last');
- }
- if (!skip_margin)
- np.style.marginLeft = '5px';
- pelm.appendChild(np);
- skip_margin = false;
- }
- };
-
- var mangle_list = function() {
- var header = document.getElementsByClassName('ForumHeader')[0];
- var filter = !ftl.settings && !ftl.author && settings.get('hide_threads');
- var sku_re = new RegExp('fasttechcdn.com/[0-9]+/([0-9]+)/.*');
- var author_re = new RegExp('started\\W+by\\W+(\\w+)');
- if (header !== undefined) {
- var ch = header.parentElement.children;
- for (var i = 1; i < ch.length; i += 2) {
- var tr = ch[i];
- var tl = tr.getElementsByClassName('ThreadLink')[0];
- var tid;
- if (tl !== undefined &&
- (settings.get('track_posts') || settings.get('track_viewed'))) {
- tid = parseInt(tl.href.match(thread_id_re)[1]);
- if (!isNaN(tid))
- last_viewed.get(tid, add_last_viewed, tl);
- }
- var img = tr.firstElementChild.firstElementChild;
- if (img && img.tagName === 'IMG') {
- var sku = img.src.match(sku_re);
- if (sku !== null) {
- var p = img.parentElement;
- var a = document.createElement('a');
- a.href = '/products/' + sku[1];
- a.appendChild(img);
- p.appendChild(a);
- }
- }
- if (filter) {
- var u = tl.parentElement.textContent
- .match(author_re);
- if (u && u[1] && ignore_list.get(u[1])) {
- tr.style.display = 'none';
- if (tr.previousElementSibling !== header)
- tr.previousElementSibling.style.display = 'none';
- }
- }
- }
- }
- };
-
- block.watch('ready', mangle_list);
- } else { // mobile
- var add_last_viewed =
- function(elm, last_viewed_page, last_post_nr, last_post_id) {
- var rh = elm.parentElement;
- var tr = rh.parentElement;
- var p = parse_pager(tr.getElementsByClassName('pagination')[0]);
- var d = document.createElement('div');
- d.style.marginLeft = '-5px';
-
- if (settings.get('track_viewed')) {
- var lv = document.createElement('span');
- lv.innerHTML = '<a href="' +
- gen_page_link(elm.href, last_viewed_page) + '">Last viewed</a>';
- lv.className = 'btn btn-default';
- lv.style.margin = '5px';
- d.appendChild(lv);
- }
-
- var pc = (pc = tr.textContent.match(/R(eplies)?: ([0-9]+)/)) ?
- parseInt(pc[2]) : undefined;
- var unread = pc > 0 && pc >= last_post_nr;
- if ((unread || settings.get('always_unread')) &&
- settings.get('track_posts')) {
- var np = document.createElement('span');
- np.className = 'btn btn-default';
- np.style.margin = '5px';
- var npa = document.createElement('a');
- if (unread) {
- npa.innerHTML = 'Unread posts';
- npa.href = gen_page_link(elm.href,
- postnr_to_pagenr(last_post_nr, p.last), 'unread');
- npa.style.color = '#C64148';
- } else {
- npa.innerHTML = 'No unread posts';
- npa.style.color = '#888';
- npa.href = gen_page_link(elm.href,
- postnr_to_pagenr(last_post_nr, p.last), 'last');
- }
- np.appendChild(npa);
- d.appendChild(np);
- }
-
- rh.appendChild(d);
- };
-
- var mangle_list = function() {
- var filter = settings.get('hide_threads');
- var elms = document.getElementsByClassName('ListRow');
- var author_re = new RegExp('started\\W+by\\W+(\\w+)');
- for (var i = 0; i < elms.length; i++) {
- var elm = elms[i];
- var rh = elm.getElementsByClassName('RowHeading')[0];
- if (rh === undefined)
- continue;
- var l = rh.firstElementChild;
- if (l !== undefined &&
- (settings.get('track_posts') || settings.get('track_viewed'))) {
- var tid = parseInt(l.href.match(thread_id_re)[1]);
- if (!isNaN(tid))
- last_viewed.get(tid, add_last_viewed, l);
- }
-
- if (filter) {
- var u = rh.parentElement.textContent.match(author_re);
- if (u && u[1] && ignore_list.get(u[1]))
- elm.style.display = 'none';
- }
- }
- };
- block.watch('ready', function() {
- if (ftl.product) {
- // Wait for thread list to load before mangling
- var div = document.getElementById('forum');
- if (div !== null)
- new MutationObserver(function(es, mo) {
- mo.disconnect();
- mangle_list();
- }).observe(div, { childList: true });
- } else {
- mangle_list();
- }
- });
- }
- }
- if (!ftl.mobile && ftl.thread) {
- var have_itmenu = false;
- var have_itmanage = false;
- var update_itmanage = function(n, itm) {
- if (!have_itmenu)
- return;
- var div = document.getElementById('IgnorelistPopout');
- if (div === null)
- return;
-
- if (!have_itmanage && itm) {
- var frag = document.createDocumentFragment();
- var hr = document.createElement('hr');
- hr.className = 'itmanage';
- frag.appendChild(hr);
-
- var l = document.createElement('div');
- l.innerHTML = '<b>Ignored Users</b>';
- l.className = 'itmanage';
- l.style.marginTop = '10px';
- manage_menu.register(l);
- l.getElementsByClassName('il_addbtn')[0].className = 'FormButton blue';
- frag.appendChild(l);
- div.appendChild(frag);
- have_itmanage = true;
- } else if (have_itmanage) {
- var elms = div.getElementsByClassName('itmanage');
- for (var i = 0; i < elms.length; i++)
- elms[i].style.display = itm ? '' : 'none';
- }
- };
- var update_itmenu = function(n, itm) {
- if (!have_itmenu && itm) {
- var b = document.getElementsByClassName('ThreadCommandBar')[0];
- var sp = document.createElement('span');
- sp.id = 'Ignorelist';
- sp.className = 'ThreadCommand';
- sp.innerHTML = 'Settings';
- b.appendChild(sp);
-
- block.watch('late', function() {
- var div = document.createElement('div');
- div.id = 'IgnorelistPopout';
- div.className = 'PopoutPanel';
- div.align = 'left';
- div.setAttribute('style',
- 'position: absolute; background: white; padding: 20px');
- settings_menu.register(div, thread_menu);
- b.appendChild(div);
-
- PM2({par: 'Ignorelist', dupe: false});
-
- have_itmenu = true;
- block.watch('late', function() {
- update_itmanage(undefined, settings.get('inthread_manage'));
- });
- });
- } else if (have_itmenu) {
- var elm = document.getElementById('Ignorelist');
- if (elm !== null)
- elm.style.display = itm ? '' : 'none';
- }
- };
-
- post_filter.watch(gen_watch_filter(function(post) {
- var tbl = post.post_elms[0].parentElement;
- var ph = post.placeholder = document.createElement('tr');
- ph.innerHTML = '<td colspan="2" class="ForumHeader" ' +
- 'style="padding: 10px; text-align: center"><a>Post by ' +
- strip_tags(post.user) + ' hidden. Click to show.</a></td>';
- ph.firstElementChild.firstElementChild.href = 'javascript:void(0)';
- handlers.hide_toggle(ph.firstElementChild.firstElementChild, post);
- tbl.insertBefore(ph, post.post_elms[0]);
- return ph;
- }));
- settings.watch('placeholders', post_filter.update);
-
- block.watch('ready', function() {
- // Wire posts & ignorebuttons up
- ignore_buttons.set('+ ignore', '+ unignore');
- for (var i = 0; i < posts.length; i++) {
- var post = posts[i];
- var tl = post.content_elm.parentElement.parentElement.parentElement;
- post.post_elms = [tl.previousElementSibling, tl];
- var head = tl.previousElementSibling.firstElementChild.lastElementChild;
- var new_a = document.createElement('a');
- new_a.href = 'javascript:void(0)';
- head.appendChild(new_a);
- post.ignbtn = new_a;
- post.badge = tl.getElementsByClassName('Badges')[0];
- }
- post_filter.register(posts);
- ignore_buttons.register(posts);
- user_tags.register(posts);
-
- settings.watch('inthread_manage', update_itmanage);
- settings.watch('inthread_menu', update_itmenu);
- });
-
- block.watch('late', function() {
- var p = parse_pager(document.getElementsByClassName('Pager')[1]);
- var lpn = (p.cur - 1) * 10 + posts.length;
- var lp = parseInt(posts[posts.length - 1].content_elm.id.slice(4));
- if (!ftl.perma)
- last_viewed.set(thread_id, p.cur, lpn, lp);
- });
-
- if (!ftl.perma && thread_id !== undefined) {
- if (location.hash !== '')
- scroll_to_hash();
- }
- }
- if (ftl.mobile && ftl.thread) {
- post_filter.watch(gen_watch_filter(function(post) {
- var tbl = post.post_elms[0].parentElement;
- var ph = post.placeholder = document.createElement('div');
- ph.className = 'col-xs-12 ListRow';
- ph.style.paddingBottom = '5px';
- ph.style.textAlign = 'center';
- ph.innerHTML = '<a>Post by ' + strip_tags(post.user) +
- ' hidden. Click to show.</a>';
- ph.firstElementChild.href = 'javascript:void(0)';
- handlers.hide_toggle(ph.firstElementChild, post);
- tbl.insertBefore(ph, post.post_elms[0]);
- return ph;
- }));
- settings.watch('placeholders', post_filter.update);
-
- ignore_buttons.set(' Ignore', ' Unignore');
-
- var have_itmenu = false;
- var have_itmanage = false;
- var update_itmanage = function(n, itm) {
- if (!have_itmenu)
- return;
- var menu = document.getElementById('hideSettings');
- if (menu === null)
- return;
- if (!have_itmanage && itm) {
- var frag = document.createDocumentFragment();
- var inner = menu.getElementsByClassName('panel-body')[0];
- var hr = document.createElement('hr');
- hr.className = 'itmanage';
- frag.appendChild(hr);
- var l = document.createElement('div');
- l.className = 'itmanage';
- l.innerHTML = '<b>Ignored Users</b>';
- l.style.marginTop = '10px';
- manage_menu.register(l);
- l.getElementsByClassName('il_addbtn')[0].remove();
- frag.appendChild(l);
- inner.appendChild(frag);
- have_itmanage = true;
- } else if (have_itmanage) {
- var elms = menu.getElementsByClassName('itmanage');
- for (var i = 0; i < elms.length; i++)
- elms[i].style.display = itm ? '' : 'none';
- }
- };
- var update_itmenu = function(n, itm) {
- if (!have_itmenu && itm) {
- var div = document.createElement('div');
- div.id = 'itmenu';
- div.className = 'panel panel-default';
- div.innerHTML = '<div class="panel-heading"><h5 class="panel-title">' +
- '<a href="#hideSettings" data-toggle="collapse">Settings ' +
- '<span class="caret"></span></a></h5>' +
- '<div id="hideSettings" class="panel-collapse collapse">' +
- '<div class="panel-body"></div></div>';
- block.watch('late', function() {
- var inner = div.getElementsByClassName('panel-body')[0];
- settings_menu.register(inner, thread_menu);
- document.getElementsByClassName('body-content')[0].appendChild(div);
-
- have_itmenu = true;
- if (settings.get('inthread_manage') !== undefined)
- update_itmanage(undefined, settings.get('inthread_manage'));
- });
- } else if (have_itmenu) {
- document.getElementById('itmenu').style.display = itm ? '' : 'none';
- }
- };
-
- block.watch('ready', function() {
- for (var i = 0; i < posts.length; i++) {
- var post = posts[i];
- var pe = post.content_elm.parentElement;
- post.post_elms = [pe];
- var menu = pe.firstElementChild.lastElementChild;
-
- var li = document.createElement('li');
- li.setAttribute('role', 'presentation');
- li.innerHTML = '<a tabindex="-1" role="menuitem">' +
- '<span class="glyphicon glyphicon-plus red"></span><span></span></a>';
- li.firstElementChild.href = 'javascript:void(0)';
- var rp = menu.lastElementChild;
- if (!rp.firstElementChild.lastChild.data.startsWith(' Report'))
- rp = rp.previousElementSibling;
- menu.insertBefore(li, rp);
- post.ignbtn = li.firstElementChild.lastElementChild;
-
- var badge = menu.firstElementChild.firstElementChild;
- var m = badge.innerHTML.match(/(.*)\((.*)\)/);
- badge.innerHTML = m[1] + '(<span>' + m[2] + '</span>)';
- post.badge = badge.lastElementChild;
- }
- post_filter.register(posts);
- ignore_buttons.register(posts);
- user_tags.register(posts);
-
- settings.watch('inthread_manage', update_itmanage);
- settings.watch('inthread_menu', update_itmenu);
- });
-
- block.watch('late', function() {
- var p = parse_pager(document.getElementsByClassName('pagination')[0]);
- var lpn = (p.cur - 1) * 10 + posts.length;
- var lp = parseInt(posts[posts.length - 1].content_elm.id.slice(4));
- if (!ftl.perma)
- last_viewed.set(thread_id, p.cur, lpn, lp);
- });
-
- if (!ftl.perma && thread_id !== undefined) {
- if (location.hash !== '')
- scroll_to_hash();
- }
- }
- if (ftl.new_arrivals) {
- var product_filter = (function() {
- var items;
-
- function update() {
- if (items === undefined)
- return;
-
- for (var i = 0; i < items.length; i++) {
- items[i].content_elm.style.display =
- ignore_categories.get(items[i].category) ? 'none' : '';
- }
- }
-
- return {
- register: function(list) {
- items = list;
- ignore_categories.watch('late', update);
- },
- };
- })();
-
- var catnr_re = new RegExp('categor(y|ies)/([0-9]+)/');
- var catstr_re = new RegExp('\\bf=([a-zA-Z0-9]+)');
- var catstr_cleanup_re = new RegExp('^.*=([0-9]+)$');
- var ignore_category = function(elm, cat) {
- elm.addEventListener('click', function() { ignore_categories.set(cat); });
- ignore_categories.watch('late', function(c, s) {
- if (c === cat)
- elm.checked = !s;
- });
- elm.checked = !ignore_categories.get(cat);
- };
- var add_ign_cb = function(elm) {
- try {
- var cat = atob(elm.lastElementChild.href.match(catstr_re)[1])
- .match(catstr_cleanup_re)[1];
-
- var cb = document.createElement('input');
- cb.type = 'checkbox';
- cb.style.float = 'right';
- cb.style.margin = '2px -2px 0px -11px';
- ignore_category(cb, cat);
- elm.insertBefore(cb, elm.firstElementChild);
- } catch (e) {}
- };
-
- block.watch('ready', function() {
- var container = ftl.mobile ?
- document.getElementsByClassName('ProductsGrid')[0] :
- document.getElementById('Products_Grid');
- if (container === null || container === undefined)
- return;
-
- var list = [];
- for (var elm = container.firstElementChild; elm !== null;
- elm = elm.nextElementSibling) {
- try {
- var cat = elm.lastElementChild.lastElementChild.firstElementChild.href
- .match(catnr_re)[2];
- list.push({ content_elm: elm, category: cat });
- } catch (e) {}
- }
- product_filter.register(list);
-
- var cats, i;
- if (ftl.mobile) {
- var heads = document.getElementsByClassName('panel-heading');
- for (i = 0; i < heads.length; i++) {
- if (heads[i].textContent.trim() === 'Category') {
- cats = heads[i];
- break;
- }
- }
- if (cats === undefined)
- return;
-
- cats = cats.parentElement.lastElementChild.firstElementChild;
- while (cats !== null) {
- add_ign_cb(cats.lastElementChild);
- cats = cats.nextElementSibling;
- }
- } else {
- var groups = document.getElementsByClassName('FilterGroup');
-
- for (i = 0; i < groups.length; i++) {
- if (groups[i].textContent.trim() === 'Category') {
- cats = groups[i];
- break;
- }
- }
- if (cats === undefined)
- return;
-
- cats = cats.nextElementSibling;
- while (cats !== null && cats.classList.contains('FilterEntry')) {
- add_ign_cb(cats);
- cats = cats.nextElementSibling;
- }
- }
- });
- }
- // Mobile reviews don't show tags
- if (ftl.reviews && !ftl.mobile) {
- var reg_tags = function(badges) {
- var posts = [];
- for (var i in badges) {
- var badge = badges[i];
- if (badge.innerText === '' ||
- !badge.previousElementSibling ||
- badge.previousElementSibling.className !== 'Nickname')
- continue;
- posts.push({
- user: badge.previousElementSibling.innerText.trim(),
- badge: badge,
- });
- }
- if (posts.length !== 0)
- user_tags.register(posts);
- };
-
- block.watch('ready', function() {
- var badges = document.getElementsByClassName('Badges');
- if (badges.length !== 0) {
- reg_tags(badges);
- } else {
- var elm;
- if (!ftl.mobile)
- elm = document.getElementById('Reviews-tab');
- else
- elm = document.getElementById('reviews');
- if (elm !== null) {
- new MutationObserver(function(es, mo) {
- mo.disconnect();
- reg_tags(document.getElementsByClassName('Badges'));
- }).observe(elm, { childlist: true });
- }
- }
- });
- }
- if (!ftl.mobile) {
- if (ftl.prsearch) {
- var search = location.href.match(/\/search(\/([0-9]+)?-?(.*))?\?([^&]+)/);
- if (search !== null) {
- if (!search[2])
- search[2] = '0';
- var sortcookie = document.cookie.match(/\bsort=([a-zA-Z0-9]+)/);
- sortcookie = sortcookie ? sortcookie[1] : 'r';
- location.replace(location.origin +
- '/category/' + search[2] + '/search/-/p/0?f=-&keywords=' + search[4] +
- '&sort=' + sortcookie);
- }
- }
-
- if (ftl.prcategory && location.search) {
- block.watch('ready', function() {
- var sortelm = document.getElementById('content_SortOrder');
- if (sortelm) {
- sortelm.onchange = function() {
- document.cookie = 'sort=' + this.value + ';path=/';
- location.href = location.href.replace(/\bsort=[^&]*/, '') +
- '&sort=' + this.value;
- };
- }
-
- var searchcat = document.getElementById('searchBarCategory');
- var urlcat = location.search.match(/\bf=([a-zA-Z0-9]+)/);
- if (searchcat !== null && urlcat !== null) {
- searchcat.value = atob(urlcat[1]).replace(/^.*=/, '');
- if (!searchcat.value)
- searchcat.value = '';
- }
- });
- }
- } else {
- if (ftl.prsearch) {
- var search = location.href.match(/\/search\/([0-9]+).*\?(.*)/);
- if (search !== null) {
- var sortcookie = document.cookie.match(/\bsort=([a-zA-Z0-9]+)/);
- sortcookie = sortcookie ? sortcookie[1] : '0';
- location.replace(location.origin +
- '/c/' + search[1] + '/-/-/p/0?f=-&sort=' + sortcookie +
- '&' + search[2]);
- }
- }
-
- if (ftl.prcategory) {
- var fix_onclick = function(elm, sortnr) {
- elm.onclick = function() {
- document.cookie = 'sort=' + sortnr + ';path=/';
- location.href = location.href.replace(/\bsort=[^&]*/, '') +
- '&sort=' + sortnr;
- };
- };
-
- block.watch('ready', function () {
- try {
- var li = document.querySelector('.clearfix button .glyphicon-sort')
- .parentElement.parentElement.lastElementChild.firstElementChild;
- for ( ; li !== null; li = li.nextElementSibling) {
- console.log(li);
- var inner = li.firstElementChild;
- var sortnr = String.match(inner.onclick, /\bsort=([0-9]+)/);
- if (sortnr === null)
- continue;
- fix_onclick(inner, sortnr[1]);
- }
- } catch (e) {}
- });
- }
- }
- if (ftl.settings) {
- block.watch('ready', function() {
- var panel = document.getElementsByClassName('PageContentPanel')[0];
- var div = document.createElement('div');
- div.style.marginTop = '5px';
- div.innerHTML = '<table style="width: auto"><tbody><tr><td class="MediumL' +
- 'abel Bold EndOfInlineSection" style="padding: 5px">Ignored Users</td' +
- '><td width=15></td><td class="MediumLabel Bold EndOfInlineSection" s' +
- 'tyle="padding: 5px">FastTech Forum Enhancements Settings</td></tr><t' +
- 'r><td style="padding: 0px"><div class="BGShadow" style="padding: 10p' +
- 'x"></div></td><td width=15></td><td style="padding:10px"><div class=' +
- '"BGShadow" style="padding: 0px"></div></td></tr></tbody></table>';
-
- var divs = div.getElementsByTagName('div');
- settings_menu.register(divs[1], full_menus);
- manage_menu.register(divs[0]);
- divs[0].getElementsByClassName('il_addbtn')[0].className =
- 'FormButton blue';
- panel.appendChild(div);
- });
- }