diff --git a/bubble-server/src/main/resources/bubble/rule/bblock/BubbleBlockRuleDriver_stats.js.hbs b/bubble-server/src/main/resources/bubble/rule/bblock/BubbleBlockRuleDriver_stats.js.hbs index 11f109da..50ed20e2 100644 --- a/bubble-server/src/main/resources/bubble/rule/bblock/BubbleBlockRuleDriver_stats.js.hbs +++ b/bubble-server/src/main/resources/bubble/rule/bblock/BubbleBlockRuleDriver_stats.js.hbs @@ -143,7 +143,17 @@ const {{JS_PREFIX}}_app = { onReady: function () { {{JS_PREFIX}}_load_messages('web_', function (messages) { {{JS_PREFIX}}_messages = messages; - }) + }); + document.onkeydown = function(e) { + e = e || window.event; + let isEscape = false; + if ("key" in e) { + isEscape = (e.key === "Escape" || e.key === "Esc"); + } else { + isEscape = (e.keyCode === 27); + } + if (isEscape) {{JS_PREFIX}}_hide_app_details(); + }; {{JS_PREFIX}}_app_refresh_interval = window.setInterval({{JS_PREFIX}}_app_refresh, 5000); } }; diff --git a/bubble-server/src/main/resources/bubble/rule/social/block/JsUserBlockerRuleDriver.js.hbs b/bubble-server/src/main/resources/bubble/rule/social/block/JsUserBlockerRuleDriver.js.hbs index 2a1b0924..0ba0516b 100644 --- a/bubble-server/src/main/resources/bubble/rule/social/block/JsUserBlockerRuleDriver.js.hbs +++ b/bubble-server/src/main/resources/bubble/rule/social/block/JsUserBlockerRuleDriver.js.hbs @@ -16,7 +16,7 @@ let {{JS_PREFIX}}_messages = null; const {{PAGE_PREFIX}}_block_keyword_tally = {}; const {{PAGE_PREFIX}}_block_author_tally = {}; -const {{PAGE_PREFIX}}_allow_tally = {}; +let {{PAGE_PREFIX}}_allow_tally = 0; function {{JS_PREFIX}}_tally_keyword_block(name) { {{JS_PREFIX}}_incr_tally(name, {{PAGE_PREFIX}}_block_keyword_tally); @@ -42,12 +42,12 @@ function {{JS_PREFIX}}_tally_author_block(name) { {{JS_PREFIX}}_incr_tally(name, {{PAGE_PREFIX}}_block_author_tally); } -function {{JS_PREFIX}}_tally_allow(name) { - {{JS_PREFIX}}_incr_tally(name, {{PAGE_PREFIX}}_allow_tally); +function {{JS_PREFIX}}_tally_allow() { + {{PAGE_PREFIX}}_allow_tally++; } -function {{JS_PREFIX}}_untally_allow(name) { - {{JS_PREFIX}}_decr_tally(name, {{PAGE_PREFIX}}_allow_tally); +function {{JS_PREFIX}}_untally_allow() { + {{PAGE_PREFIX}}_allow_tally--; } function {{JS_PREFIX}}_uuidv4() { @@ -209,14 +209,14 @@ function {{JS_PREFIX}}_includes_block_keyword (element, firstEval) { let cskw = kw.substring(1); if (html.indexOf(cskw) !== -1) { // {{PAGE_PREFIX}}_log('>>> includes_block_keyword: blocking based on case-sensitive keyword: ' + cskw); - {{JS_PREFIX}}_tally_block('*'+cskw); + {{JS_PREFIX}}_tally_keyword_block(cskw); if (!firstEval) {{JS_PREFIX}}_untally_allow(); return true; } } else { if (html.toLowerCase().indexOf(kw.toLowerCase()) !== -1) { // {{PAGE_PREFIX}}_log('>>> includes_block_keyword: blocking based on case-insensitive keyword: ' + kw); - {{JS_PREFIX}}_tally_block('*'+kw); + {{JS_PREFIX}}_tally_keyword_block(kw); if (!firstEval) {{JS_PREFIX}}_untally_allow(); return true; } @@ -323,12 +323,68 @@ function {{JS_PREFIX}}_show_app_details() { detailsDiv.appendChild({{JS_PREFIX}}_app_title_span('ShadowBan')); detailsDiv.appendChild(document.createElement('hr')); + const recentBlocksText = {{PAGE_PREFIX}}_msg_or_default({{JS_PREFIX}}_messages, 'web_recentBlocks', 'Recent Blocks'); + const recentBlocksHeader = document.createElement('strong') + recentBlocksHeader.appendChild(document.createTextNode(recentBlocksText)); + detailsDiv.appendChild(recentBlocksHeader); + + const keywordTally = {{PAGE_PREFIX}}_block_keyword_tally; + let keywordTallyKeys = Object.keys({{PAGE_PREFIX}}_block_keyword_tally); + const authorTally = {{PAGE_PREFIX}}_block_author_tally; + let authorTallyKeys = Object.keys({{PAGE_PREFIX}}_block_author_tally); + if (keywordTallyKeys.length === 0 && authorTallyKeys.length === 0) { + const noRecentBlocksText = {{PAGE_PREFIX}}_msg_or_default({{JS_PREFIX}}_messages, 'web_noRecentBlocks', '(empty)'); + detailsDiv.appendChild(document.createElement('br')); + detailsDiv.appendChild(document.createTextNode(noRecentBlocksText)); + } else { + let totalBlocks = 0; + if (keywordTallyKeys.length > 0) { + keywordTallyKeys = keywordTallyKeys.slice(); + keywordTallyKeys.sort(function (a, b) { + return a.localeCompare(b, '{{ACCOUNT_LANG}}', {'sensitivity': 'base'}); + }); + const openQuote = {{PAGE_PREFIX}}_msg_or_default({{JS_PREFIX}}_messages, 'web_openQuote', '“'); + const closeQuote = {{PAGE_PREFIX}}_msg_or_default({{JS_PREFIX}}_messages, 'web_closeQuote', '”'); + keywordTallyKeys.forEach(keyword => { + const count = keywordTally[keyword]; + totalBlocks += count; + const entryDiv = document.createElement('div'); + const em = document.createElement('em'); + em.appendChild(document.createTextNode(openQuote + keyword + closeQuote + ': ' + count)); + entryDiv.appendChild(em); + detailsDiv.appendChild(entryDiv); + }); + } + if (authorTallyKeys.length > 0) { + authorTallyKeys = authorTallyKeys.slice(); + authorTallyKeys.sort(function (a, b) { + return a.localeCompare(b, '{{ACCOUNT_LANG}}', {'sensitivity': 'base'}); + }); + authorTallyKeys.forEach(author => { + const count = authorTally[author]; + totalBlocks += count; + const entryDiv = document.createElement('div'); + entryDiv.appendChild(document.createTextNode(author + ': ' + count)); + detailsDiv.appendChild(entryDiv); + }); + } + const summaryDiv = document.createElement('div'); + const summaryHeader = document.createElement('strong'); + const summaryLabel = {{PAGE_PREFIX}}_msg_or_default({{JS_PREFIX}}_messages, 'web_signalNoiseRatio', 'signal/noise'); + const totalAllowed = {{PAGE_PREFIX}}_allow_tally; + const fullTotal = totalAllowed + totalBlocks; + const ratio = 100.0 * (totalAllowed / fullTotal); + summaryHeader.appendChild(document.createTextNode(summaryLabel + ': ' + totalAllowed + '/' + totalBlocks + ' ≈ ' + ratio.toLocaleString('{{ACCOUNT_LOCALE_HYPHEN}}', { maximumSignificantDigits: 3 }) + '%')); + summaryDiv.appendChild(summaryHeader); + detailsDiv.appendChild(summaryDiv); + } + detailsDiv.appendChild(document.createElement('hr')); + let blocks = Object.keys({{JS_PREFIX}}_blocked_users); if (blocks !== null && blocks.length > 0) { blocks = blocks.slice(); // copy first, then sort case insensitive using user's locale blocks.sort(function (a, b) { return a.localeCompare(b, '{{ACCOUNT_LANG}}', {'sensitivity': 'base'}); - return a.localeCompare(b, '{{ACCOUNT_LANG}}', {'sensitivity': 'base'}); }); } let keywords = Object.keys({{JS_PREFIX}}_blocked_keywords); @@ -508,7 +564,17 @@ function {{JS_PREFIX}}_toggle_app_details(ev) { onReady: function () { {{JS_PREFIX}}_load_messages('web_', function (messages) { {{JS_PREFIX}}_messages = messages; - }) + }); + document.onkeydown = function(e) { + e = e || window.event; + let isEscape = false; + if ("key" in e) { + isEscape = (e.key === "Escape" || e.key === "Esc"); + } else { + isEscape = (e.keyCode === 27); + } + if (isEscape) {{JS_PREFIX}}_hide_app_details(); + }; {{JS_PREFIX}}_fetch_blocks(); } }); diff --git a/bubble-server/src/main/resources/bubble/rule/social/block/site/FB.js.hbs b/bubble-server/src/main/resources/bubble/rule/social/block/site/FB.js.hbs index 3d87773f..2f30309d 100644 --- a/bubble-server/src/main/resources/bubble/rule/social/block/site/FB.js.hbs +++ b/bubble-server/src/main/resources/bubble/rule/social/block/site/FB.js.hbs @@ -147,7 +147,7 @@ function {{JS_PREFIX}}_should_block(blocked_users, article) { if (authorName.endsWith('/')) authorName = authorName.substring(0, authorName.length-1); if (authorName === 'profile.php') { // log('should_block returning true for '+authorName); - {{JS_PREFIX}}_tally_block({{PAGE_PREFIX}}_msg_or_default({{JS_PREFIX}}_messages, 'web_advertOrOtherBlock', 'ad/other')); + {{JS_PREFIX}}_tally_author_block({{PAGE_PREFIX}}_msg_or_default({{JS_PREFIX}}_messages, 'web_advertOrOtherBlock', 'ad/other')); if (!firstEval) {{JS_PREFIX}}_untally_allow(authorName); return true; } @@ -158,14 +158,14 @@ function {{JS_PREFIX}}_should_block(blocked_users, article) { const authorDisplayName = authorDisplay.innerHTML; if ({{JS_PREFIX}}_is_ad(article)) { // log('removing ad ('+authorDisplayName+')'); - {{JS_PREFIX}}_tally_block(authorName == null ? {{PAGE_PREFIX}}_msg_or_default({{JS_PREFIX}}_messages, 'web_advertOrOtherBlock', 'ad/other') : authorName); - if (!firstEval) {{JS_PREFIX}}_untally_allow(authorName); + {{JS_PREFIX}}_tally_author_block(authorName == null ? {{PAGE_PREFIX}}_msg_or_default({{JS_PREFIX}}_messages, 'web_advertOrOtherBlock', 'ad/other') : authorName); + if (!firstEval) {{JS_PREFIX}}_untally_allow(); return authorName == null ? true : authorName; } else if (authorName in blocked_users) { // log('should_block returning '+authorName); - {{JS_PREFIX}}_tally_block(authorName == null ? {{PAGE_PREFIX}}_msg_or_default({{JS_PREFIX}}_messages, 'web_advertOrOtherBlock', 'ad/other') : authorName); - if (!firstEval) {{JS_PREFIX}}_untally_allow(authorName); + {{JS_PREFIX}}_tally_author_block(authorName == null ? {{PAGE_PREFIX}}_msg_or_default({{JS_PREFIX}}_messages, 'web_advertOrOtherBlock', 'ad/other') : authorName); + if (!firstEval) {{JS_PREFIX}}_untally_allow(); return authorName == null ? true : authorName; } else { @@ -194,7 +194,7 @@ function {{JS_PREFIX}}_should_block(blocked_users, article) { } if (firstEval) { // console.log('>>> allowing post with firstAuthor = '+firstAuthor); - {{JS_PREFIX}}_tally_allow(firstAuthor); + {{JS_PREFIX}}_tally_allow(); } return false; } diff --git a/bubble-server/src/main/resources/bubble/rule/social/block/site/HackerNews.js.hbs b/bubble-server/src/main/resources/bubble/rule/social/block/site/HackerNews.js.hbs index 6035d3b6..473d2f79 100644 --- a/bubble-server/src/main/resources/bubble/rule/social/block/site/HackerNews.js.hbs +++ b/bubble-server/src/main/resources/bubble/rule/social/block/site/HackerNews.js.hbs @@ -40,7 +40,7 @@ function {{JS_PREFIX}}_apply_blocks(blocked_users) { const authorBlocked = author in blocked_users; if (authorBlocked || {{JS_PREFIX}}_includes_block_keyword(comment, firstEval)) { if (authorBlocked) { - {{JS_PREFIX}}_tally_block(author); + {{JS_PREFIX}}_tally_author_block(author); if (!firstEval) {{JS_PREFIX}}_untally_allow(); } blocking = true; @@ -54,7 +54,7 @@ function {{JS_PREFIX}}_apply_blocks(blocked_users) { blockNode.className = "bubble_block"; blockNode.innerHTML = ' [X]'; ageElement.parentNode.insertBefore(blockNode, ageElement.nextSibling); - {{JS_PREFIX}}_tally_allow(author); + {{JS_PREFIX}}_tally_allow(); } } } diff --git a/bubble-server/src/main/resources/bubble/rule/social/block/site/MR.js.hbs b/bubble-server/src/main/resources/bubble/rule/social/block/site/MR.js.hbs index 74263d9c..f8d1682e 100644 --- a/bubble-server/src/main/resources/bubble/rule/social/block/site/MR.js.hbs +++ b/bubble-server/src/main/resources/bubble/rule/social/block/site/MR.js.hbs @@ -22,7 +22,7 @@ function {{JS_PREFIX}}_consider_block(comments, blocked_users) { if (userElement !== null) { const author = userElement.innerText; if (author in blocked_users) { - {{JS_PREFIX}}_tally_block(author); + {{JS_PREFIX}}_tally_author_block(author); if (!firstEval) {{JS_PREFIX}}_untally_allow(); comment.parentNode.removeChild(comment); continue; @@ -34,7 +34,7 @@ function {{JS_PREFIX}}_consider_block(comments, blocked_users) { blockNode.style['white-space'] = 'nowrap'; blockNode.innerHTML = '[X]  '; userElement.parentNode.insertBefore(blockNode, userElement); - {{JS_PREFIX}}_tally_allow(author); + {{JS_PREFIX}}_tally_allow(); } } } diff --git a/bubble-server/src/main/resources/bubble/rule/social/block/site/Reason.js.hbs b/bubble-server/src/main/resources/bubble/rule/social/block/site/Reason.js.hbs index 9d84c7b1..661a036d 100644 --- a/bubble-server/src/main/resources/bubble/rule/social/block/site/Reason.js.hbs +++ b/bubble-server/src/main/resources/bubble/rule/social/block/site/Reason.js.hbs @@ -23,7 +23,7 @@ function {{JS_PREFIX}}_consider_block(comments, blocked_users) { if (userElement !== null) { const author = userElement.innerText; if (author in blocked_users) { - {{JS_PREFIX}}_tally_block(author); + {{JS_PREFIX}}_tally_author_block(author); if (!firstEval) {{JS_PREFIX}}_untally_allow(); comment.parentNode.removeChild(comment); continue; @@ -39,7 +39,7 @@ function {{JS_PREFIX}}_consider_block(comments, blocked_users) { if (replies !== null) { {{JS_PREFIX}}_consider_block(replies.querySelector('li.comment')); } - {{JS_PREFIX}}_tally_allow(author); + {{JS_PREFIX}}_tally_allow(); } } } diff --git a/bubble-server/src/main/resources/bubble/rule/social/block/site/Twitter.js.hbs b/bubble-server/src/main/resources/bubble/rule/social/block/site/Twitter.js.hbs index 0ba1fd4d..644111f2 100644 --- a/bubble-server/src/main/resources/bubble/rule/social/block/site/Twitter.js.hbs +++ b/bubble-server/src/main/resources/bubble/rule/social/block/site/Twitter.js.hbs @@ -41,7 +41,7 @@ function {{JS_PREFIX}}_apply_blocks(blocked_users) { const authorBlocked = authorName in blocked_users; if (authorBlocked || {{JS_PREFIX}}_includes_block_keyword(node)) { if (authorBlocked) { - {{JS_PREFIX}}_tally_block(authorName); + {{JS_PREFIX}}_tally_author_block(authorName); if (!firstEval) {{JS_PREFIX}}_untally_allow(); } console.log('removing post by author: ' + authorName); @@ -96,7 +96,7 @@ function {{JS_PREFIX}}_apply_blocks(blocked_users) { authorDiv.setAttribute('white-space', 'no-wrap'); authorDiv.parentNode.appendChild(blockControl); - {{JS_PREFIX}}_tally_allow(authorName); + {{JS_PREFIX}}_tally_allow(); } } } diff --git a/bubble-server/src/main/resources/models/apps/user_block/bubbleApp_userBlock.json b/bubble-server/src/main/resources/models/apps/user_block/bubbleApp_userBlock.json index 8c0fa9e6..7dc5493f 100644 --- a/bubble-server/src/main/resources/models/apps/user_block/bubbleApp_userBlock.json +++ b/bubble-server/src/main/resources/models/apps/user_block/bubbleApp_userBlock.json @@ -46,6 +46,10 @@ {"name": "web_noKeywordsBlocked", "value": "(empty)"}, {"name": "web_addKeyword", "value": "add"}, {"name": "web_advertOrOtherBlock", "value": "advert/other"}, + {"name": "web_recentBlocks", "value": "Recent Blocks"}, + {"name": "web_noRecentBlocks", "value": "(empty)"}, + {"name": "web_openQuote", "value": "“"}, + {"name": "web_closeQuote", "value": "”"}, {"name": "web_signalNoiseRatio", "value": "signal/noise"}, {"name": "web_close", "value": "close"}, {"name": "web_blockedKeywordLists", "value": "Keyword Lists"},