diff --git a/.gitignore b/.gitignore index 6311779..70a1f6a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ +node_modules/ web-ext-artifacts/ diff --git a/README.md b/README.md index ea3bb12..c28964c 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ The following will now be hidden in topics (and when posting replies): - "You are ignoring this user" placeholders for posts by ignored users - Posts which quote an ignored user -Topics created by ignored users will also be hidden. +Topics created by ignored users will also be hidden by default. ## After installing @@ -39,7 +39,7 @@ To temporarily view hidden posts, open your browser's right-click/context menu a |:-------:|:------:| | ![Screenshot of the 'Show ignored posts' menu item in Firefox](screenshots/firefox_context_menu.png) | ![Screenshot of the 'Show ignored posts' menu item in Chrome](screenshots/chrome_context_menu.png) | -Ignored posts will be displayed with a fetching salmon highlight, with a new "Remove from ignore list" control added to ignored users: +Ignored posts will be displayed, with a new "Remove from ignore list" control added to ignored users: ![Screenshot of ignored posts being shown](screenshots/showing_ignored_posts.png) diff --git a/background.js b/background.js index 405bc44..270044e 100644 --- a/background.js +++ b/background.js @@ -11,7 +11,7 @@ chrome.storage.local.get((config) => { chrome.storage.local.set({showIgnoredPosts: !showIgnoredPosts}) }, documentUrlPatterns: [ - 'https://www.cookdandbombd.co.uk/forums/index.php/topic*', + 'https://www.cookdandbombd.co.uk/forums/index.php?topic*', 'https://www.cookdandbombd.co.uk/forums/index.php?action=post*' ], }) diff --git a/cookdandbombdreallyignoreusers.user.js b/cookdandbombdreallyignoreusers.user.js index e674996..a430231 100644 --- a/cookdandbombdreallyignoreusers.user.js +++ b/cookdandbombdreallyignoreusers.user.js @@ -2,9 +2,9 @@ // @name Cook'd and Bomb'd Really Ignore Users // @description Really ignores ignored users // @namespace https://github.com/insin/greasemonkey/ -// @version 2 -// @match https://www.cookdandbombd.co.uk/forums/index.php/board* -// @match https://www.cookdandbombd.co.uk/forums/index.php/topic* +// @version 3 +// @match https://www.cookdandbombd.co.uk/forums/index.php?board* +// @match https://www.cookdandbombd.co.uk/forums/index.php?topic* // @match https://www.cookdandbombd.co.uk/forums/index.php?action=post* // @match https://www.cookdandbombd.co.uk/forums/index.php?action=profile;area=lists;sa=ignore* // @match https://www.cookdandbombd.co.uk/forums/index.php?action=unread* @@ -35,20 +35,8 @@ function addIgnoredPostsStyle() { } .cab_ignoredPost.cab_show { display: block; + background-color: #ddd !important; } - .cab_ignoredPost.cab_show { - background-color: #fdd !important; - } - .cab_ignoredPost.cab_show { - background-color: #fdd !important; - border-radius: 0.7em; - } - .cab_ignoredPost.cab_show span.topslice, - .cab_ignoredPost.cab_show span.topslice span, - .cab_ignoredPost.cab_show span.botslice, - .cab_ignoredPost.cab_show span.botslice span { - background-image: none !important; - } `) } @@ -65,10 +53,27 @@ function toggleShowIgnoredPosts(showIgnoredPosts) { posts.forEach(post => post.updateClassNames()) } +/** + * Topics being hidden breaks the CSS nth-of-type striping. + */ +function reStripePosts() { + let odd = true + posts.forEach(post => { + if (!post.isIgnored()) { + post.$el.classList.toggle('odd', odd) + post.$el.classList.toggle('even', !odd) + odd = !odd + } else { + post.$el.classList.remove('odd') + post.$el.classList.remove('even') + } + }) +} + function TopicPage() { addIgnoredPostsStyle() - let isLoggedIn = document.querySelector('#guest_form') == null + let isLoggedIn = document.querySelector('#profile_menu_top') != null let ignoredUsers let ignoredUserIds @@ -80,12 +85,12 @@ function TopicPage() { ignoredUserNames = ignoredUsers.map(user => user.name) } - function configureIgnoreControl({$a, $img, userId, userName}) { + function configureIgnoreControl({$a, $span, userId, userName}) { let isUserIgnored = ignoredUserIds.includes(userId) $a.href = `https://www.cookdandbombd.co.uk/forums/index.php?action=profile;area=lists;sa=ignore&${isUserIgnored ? `unignore=${userId}` : `ignore=${userName}`}` $a.title = `${isUserIgnored ? 'Remove from' : 'Add to'} ignore list` - $img.alt = `${isUserIgnored ? 'Remove from' : 'Add to'} ignore list` - $img.src = `/forums/Themes/default/images/buttons/${isUserIgnored ? 'close' : 'ignore'}.gif` + $span.classList.toggle('delete', isUserIgnored) + $span.classList.toggle('ignore', !isUserIgnored) } function Post($wrapper) { @@ -93,33 +98,54 @@ function TopicPage() { let userId = $userLink.href.match(/;u=(\d+)/)[1] let userName = $userLink.textContent - let quotedUserNames = Array.from($wrapper.querySelectorAll('div.topslice_quote a')).map($a => $a.textContent.match(/Quote from: (.+) on /)[1]) + let quotedUserNames = Array.from($wrapper.querySelectorAll('.post blockquote cite a')).map( + $a => $a.textContent.match(/Quote from: (.+) on /)?.[1] || $a.textContent.match(/Quote from: (.+)/)?.[1] + ).filter(Boolean) let api = { - updateClassNames() { + $el: $wrapper, + isIgnored() { let isUserIgnored = ignoredUserIds.includes(userId) let quotesIgnoredUser = config.hidePostsQuotingIgnoredUsers && quotedUserNames.some(userName => ignoredUserNames.includes(userName)) - let isPostIgnored = isUserIgnored || quotesIgnoredUser - $wrapper.parentElement.classList.toggle('cab_ignoredPost', isPostIgnored) - $wrapper.parentElement.classList.toggle('cab_show', config.showIgnoredPosts && isPostIgnored) + return isUserIgnored || quotesIgnoredUser + }, + updateClassNames() { + let isPostIgnored = api.isIgnored() + $wrapper.classList.toggle('cab_ignoredPost', isPostIgnored) + $wrapper.classList.toggle('cab_show', config.showIgnoredPosts && isPostIgnored) } } // Add an ignore/unignore link to user profiles in posts if (config.addIgnoreUserControlToPosts) { let $a = document.createElement('a') - let $img = document.createElement('img') - $a.appendChild($img) + let $span = document.createElement('span') + $span.className = 'main_icons centericon' + $a.appendChild($span) let $li = document.createElement('li') $li.appendChild($a) - configureIgnoreControl({$a, $img, userId, userName}) - $wrapper.querySelector('div.poster li.profile ul').appendChild($li) + configureIgnoreControl({$a, $span, userId, userName}) + let $profileIcons = $wrapper.querySelector('div.poster ol.profile_icons') + + // Logged-out users don't get a profile list item, so we'll add our own + if (!$profileIcons) { + let $insertProfileAfter = + $wrapper.querySelector('div.poster .im_icons') || + $wrapper.querySelector('div.poster .blurb') || + $wrapper.querySelector('div.poster .icons') + let $profile = document.createElement('li') + $profile.className = 'profile' + $profileIcons = document.createElement('ol') + $profileIcons.className = 'profile' + $profile.appendChild($profileIcons) + $insertProfileAfter.insertAdjacentElement('afterend', $profile) + } + + $profileIcons.appendChild($li) // For logged-out users, manage the ignore list independently if (!isLoggedIn) { - console.log('not logged in') $a.addEventListener('click', (e) => { - console.log('clicked') e.preventDefault() // Get a fresh copy in case it's been changed in another tab let ignoredUsers = getIgnoredUsers() @@ -132,8 +158,9 @@ function TopicPage() { } setIgnoredUsers(ignoredUsers) storeIgnoredUsers(ignoredUsers) - configureIgnoreControl({$a, $img, userId, userName}) + configureIgnoreControl({$a, $span, userId, userName}) posts.forEach(post => post.updateClassNames()) + reStripePosts() }) } } @@ -142,27 +169,52 @@ function TopicPage() { return api } + let postElements = Array.from(document.querySelectorAll('#forumposts > form > div.windowbg')) + let oddBg = postElements[0] ? getComputedStyle(postElements[0]).backgroundColor : null + let evenBg = postElements[1] ? getComputedStyle(postElements[1]).backgroundColor : null + + addStyle(` + .cab_ignoredPost { + display: none; + } + .cab_ignoredPost.cab_show { + display: block; + background-color: #ddd !important; + } + ${oddBg ? `#forumposts .windowbg.odd { + background-color: ${oddBg}; + }` : ''} + ${evenBg ? `#forumposts .windowbg.even { + background-color: ${evenBg}; + }` : ''} + `) + setIgnoredUsers(getIgnoredUsers()) - posts = Array.from(document.querySelectorAll('div.post_wrapper')).map($wrapper => Post($wrapper)) + posts = postElements.map(Post) + reStripePosts() document.body.classList.add('cab_reallyIgnoreUsers') } -function PostPage() { - addIgnoredPostsStyle() - +function PostReplyPage() { let ignoredUserNames = getIgnoredUsers().map(user => user.name) function Post($wrapper) { let $userHeader = $wrapper.querySelector('h5') - let userName = $userHeader.textContent.match(/Posted by: (.+)/)[1] - let isUserIgnored = ignoredUserNames.includes(userName) - let quotedUserNames = Array.from($wrapper.querySelectorAll('div.topslice_quote a')).map($a => $a.textContent.match(/Quote from: (.+) on /)[1]) - let quotesIgnoredUser = config.hidePostsQuotingIgnoredUsers && quotedUserNames.some(userName => ignoredUserNames.includes(userName)) - let isPostIgnored = isUserIgnored || quotesIgnoredUser + let userName = $userHeader?.textContent.match(/Posted by (.+)/)?.[1] + let quotedUserNames = Array.from($wrapper.querySelectorAll('blockquote cite a')).map( + $a => $a.textContent.match(/Quote from: (.+) on /)?.[1] || $a.textContent.match(/Quote from: (.+)/)?.[1] + ).filter(Boolean) let api = { + $el: $wrapper, + isIgnored() { + let isUserIgnored = ignoredUserNames.includes(userName) + let quotesIgnoredUser = config.hidePostsQuotingIgnoredUsers && quotedUserNames.some(userName => ignoredUserNames.includes(userName)) + return isUserIgnored || quotesIgnoredUser + }, updateClassNames() { + let isPostIgnored = api.isIgnored() $wrapper.classList.toggle('cab_ignoredPost', isPostIgnored) $wrapper.classList.toggle('cab_show', config.showIgnoredPosts && isPostIgnored) } @@ -172,7 +224,28 @@ function PostPage() { return api } - posts = Array.from(document.querySelectorAll('div.core_posts')).map($wrapper => Post($wrapper)) + let postElements = Array.from(document.querySelectorAll('#recent div.windowbg')) + let oddBg = postElements[0] ? getComputedStyle(postElements[0]).backgroundColor : null + let evenBg = postElements[1] ? getComputedStyle(postElements[1]).backgroundColor : null + + addStyle(` + .cab_ignoredPost { + display: none; + } + .cab_ignoredPost.cab_show { + display: block; + background-color: #ddd !important; + } + ${oddBg ? `#recent .windowbg.odd { + background-color: ${oddBg}; + }` : ''} + ${evenBg ? `#recent .windowbg.even { + background-color: ${evenBg}; + }` : ''} + `) + + posts = postElements.map(Post) + reStripePosts() document.body.classList.add('cab_reallyIgnoreUsers') } @@ -189,7 +262,9 @@ function IgnoreListPage() { // Automatically unignore a user if unignore=id is provided in the URL if (params.has('unignore')) { - let $removeLink = Array.from((document.querySelectorAll('.table_grid tr td:last-child a'))).find(a => a.href.includes(`remove=${params.get('unignore')}`)) + let $removeLink = Array.from(document.querySelectorAll('.table_grid tr td:last-child a')).find( + $a => $a.href.includes(`remove=${params.get('unignore')}`) + ) if ($removeLink) { $removeLink.click() return @@ -206,15 +281,15 @@ function IgnoreListPage() { function ForumPage() { addStyle(` - .cab_ignoredUser { + #topic_container .windowbg.cab_ignoredUser { display: none; } `) let ignoredUserIds = getIgnoredUsers().map(user => user.id) - for (let $topicRow of document.querySelectorAll('#main_content_section .table_grid tbody tr')) { - let $userLink = $topicRow.querySelector('td.subject p a') + for (let $topicRow of document.querySelectorAll('#topic_container > div')) { + let $userLink = $topicRow.querySelector('.info .floatleft a') let userId = $userLink?.href.match(/;u=(\d+)/)?.[1] if (ignoredUserIds.includes(userId)) { $topicRow.classList.add('cab_ignoredUser') @@ -225,13 +300,13 @@ function ForumPage() { if (location.search.includes('?action=profile;area=lists;sa=ignore')) { IgnoreListPage() } -else if (location.search.includes('?action=unread') || location.pathname.includes('index.php/board')) { +else if (location.search.includes('?action=unread') || location.search.includes('?board')) { if (config.hideTopicsCreatedByIgnoredUsers) { ForumPage() } } else if (!document.body.classList.contains('cab_reallyIgnoreUsers')) { - let page = location.search.includes('?action=post') ? PostPage : TopicPage + let page = location.search.includes('?action=post') ? PostReplyPage : TopicPage if (typeof GM != 'undefined') { page() GM.registerMenuCommand('Toggle ignored post display', () => { diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..2cfaeb1 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "checkJs": true, + "target": "es2016" + }, + "exclude": [ + "node_modules" + ] +} \ No newline at end of file diff --git a/manifest.json b/manifest.json index e9eaa91..0b1f957 100644 --- a/manifest.json +++ b/manifest.json @@ -4,7 +4,7 @@ "short_name": "CaB Really Ignore Users", "description": "Really ignores ignored users", "homepage_url": "https://github.com/insin/cookdandbombd-really-ignore-users", - "version": "1.1", + "version": "1.2", "icons": { "16": "icons/icon16.png", "48": "icons/icon48.png", @@ -20,8 +20,8 @@ "content_scripts": [ { "matches": [ - "https://www.cookdandbombd.co.uk/forums/index.php/board*", - "https://www.cookdandbombd.co.uk/forums/index.php/topic*", + "https://www.cookdandbombd.co.uk/forums/index.php?board*", + "https://www.cookdandbombd.co.uk/forums/index.php?topic*", "https://www.cookdandbombd.co.uk/forums/index.php?action=post*", "https://www.cookdandbombd.co.uk/forums/index.php?action=profile;area=lists;sa=ignore*", "https://www.cookdandbombd.co.uk/forums/index.php?action=unread*" diff --git a/options.css b/options.css new file mode 100644 index 0000000..30e0267 --- /dev/null +++ b/options.css @@ -0,0 +1,59 @@ +body, html { + padding: 0; + margin: 0; + font-family: Roboto, "Segoe UI", Tahoma, sans-serif; + font-size: 13px; +} + +label { + display: flex; + justify-content: space-between; + padding: 4px 12px; + margin: 8px 0; + cursor: pointer; +} + +input[type=checkbox] { + cursor: pointer; + margin-left: 12px; +} + +section:not(:first-of-type) { + border-top: 1px solid #f0f0f0; +} + +/* Firefox overrides */ +@-moz-document url-prefix() { + html { + height: 100%; + } + body { + font-family: inherit; + font-size: 15px; + height: 100%; + } + section:not(:first-of-type) { + border-color: #d7d7db; + } +} + +/* Dark mode overrides */ +@media (prefers-color-scheme: dark) { + body { + background-color: #292a2d; + color: #e8eaed; + } + section:not(:first-of-type) { + border-color: #3f4042; + } + + /* Firefox dark mode overrides */ + @-moz-document url-prefix() { + body { + background-color: #23222b; + } + section:not(:first-of-type) { + border-color: #4e4d54; + } + } +} \ No newline at end of file diff --git a/options.html b/options.html index f0b3ed5..dc49359 100644 --- a/options.html +++ b/options.html @@ -2,123 +2,34 @@ - + + Cook'd and Bomb'd Really Ignore Users Options +
diff --git a/package.json b/package.json index 18690af..dd0a3f4 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,15 @@ "ignoreFiles": [ "icons/chrome-web-store-icon.png", "icons/icon.png", + "jsconfig.json", "package.json", "README.md", "screenshots/" ] + }, + "devDependencies": { + "@types/chrome": "0.0.x", + "@types/greasemonkey": "4.x", + "web-ext": "6.x" } } \ No newline at end of file diff --git a/screenshots/chrome_context_menu.png b/screenshots/chrome_context_menu.png index e73159f..d2a4080 100644 Binary files a/screenshots/chrome_context_menu.png and b/screenshots/chrome_context_menu.png differ diff --git a/screenshots/chrome_options.png b/screenshots/chrome_options.png index d7ba86c..67a3830 100644 Binary files a/screenshots/chrome_options.png and b/screenshots/chrome_options.png differ diff --git a/screenshots/firefox_context_menu.png b/screenshots/firefox_context_menu.png index 835f300..3967aba 100644 Binary files a/screenshots/firefox_context_menu.png and b/screenshots/firefox_context_menu.png differ diff --git a/screenshots/firefox_options.png b/screenshots/firefox_options.png index 8cee032..7d5e5c2 100644 Binary files a/screenshots/firefox_options.png and b/screenshots/firefox_options.png differ diff --git a/screenshots/ignore_control.png b/screenshots/ignore_control.png index 5ec3589..a3c6151 100644 Binary files a/screenshots/ignore_control.png and b/screenshots/ignore_control.png differ diff --git a/screenshots/showing_ignored_posts.png b/screenshots/showing_ignored_posts.png index 1f3d9ec..442255f 100644 Binary files a/screenshots/showing_ignored_posts.png and b/screenshots/showing_ignored_posts.png differ