diff --git a/data/bountysource_client.js b/data/bountysource_client.js index 1223c41..dd9413d 100644 --- a/data/bountysource_client.js +++ b/data/bountysource_client.js @@ -40,5 +40,11 @@ var BountysourceClient = { setTimeout(function() { BountysourceClient.message({ action: "google_analytics", request: request }); }, 0); - } + }, + + matches: Element.prototype.matches || + Element.prototype.mozMatchesSelector || + Element.prototype.msMatchesSelector || + Element.prototype.oMatchesSelector || + Element.prototype.webkitMatchesSelector }; diff --git a/data/settings/options.css b/data/settings/options.css new file mode 100644 index 0000000..92331a8 --- /dev/null +++ b/data/settings/options.css @@ -0,0 +1,56 @@ +/*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0} + +* { + box-sizing: border-box; +} + +input[type="checkbox"] { + margin: 0px 0.5ex; +} + +h1 { + font-size: 36px; +} + +body { + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-size: 14px; + background-color: #F8F8F8; +} + +#content { + background-color: #FFF; + border: 1px solid #CCC; + border-radius: 3px; + margin: 40px auto 0; + padding: 20px 40px 30px; + width: 650px; +} + +#title { + color: #333; + font-size: 17px; + margin: 10px 0 0; + text-align: center; +} + +.option-row { + margin-top: 50px; +} + +.option-row:after { + clear: both; + content: ""; + display: table; +} + +.option-name { + float: left; + font-weight: bold; + width: 150px; +} + +.option-value { + float: left; + margin-top: -2px; +} \ No newline at end of file diff --git a/data/settings/options.html b/data/settings/options.html new file mode 100644 index 0000000..e44dba2 --- /dev/null +++ b/data/settings/options.html @@ -0,0 +1,29 @@ + + + + Bountysource Options + + + +
+
+ +
Extension Options
+
+
+
+
Thumbs up/+1:
+
+ + +
+
+
+
+ + + \ No newline at end of file diff --git a/data/settings/options.js b/data/settings/options.js new file mode 100644 index 0000000..9169ca7 --- /dev/null +++ b/data/settings/options.js @@ -0,0 +1,31 @@ +(function() { + var Options = function() { + this.hideThumbsChkbox = document.getElementById("hide-thumbs-checkbox"); + this.restoreOptions() + this.hideThumbsup(); + }; + + Options.prototype.restoreOptions = function() { + var self = this; + + chrome.storage.sync.get({ + hideThumbsup: true + }, function(items) { + self.hideThumbsChkbox.checked = items.hideThumbsup; + }); + }; + + Options.prototype.hideThumbsup = function() { + var self = this; + + self.hideThumbsChkbox.addEventListener("change", function() { + chrome.storage.sync.set({ + hideThumbsup: self.hideThumbsChkbox.checked + }); + }); + }; + + document.addEventListener('DOMContentLoaded', function() { + new Options() + }); +})(); \ No newline at end of file diff --git a/data/stylesheets/thumbs.css b/data/stylesheets/thumbs.css index 3b40276..fdb1197 100644 --- a/data/stylesheets/thumbs.css +++ b/data/stylesheets/thumbs.css @@ -52,3 +52,5 @@ .bountysource-thumbs-jira .issue-header .issue-header-content { margin-left: 60px; } .bountysource-thumbs-jira .bountysource-thumbs-box { margin-left: 10px; margin-top: 10px; z-index: 1000; } +.bountysource-comment-hide {display: none !important;} + diff --git a/data/thumbs.js b/data/thumbs.js index b7b3abf..b3e357c 100644 --- a/data/thumbs.js +++ b/data/thumbs.js @@ -147,6 +147,103 @@ } }; + var ThumbHide = function() { + this.hideAllThumbs(); + }; + + ThumbHide.prototype.hideAllThumbs = function() { + var that = this; + var hideAll = function() { + var comments = [].slice.call(document.querySelectorAll(".comment-body")); + var commentsHidden = 0; + var hideTimelineWrapper = function(node) { + while (node = node.parentElement) { + if (BountysourceClient.matches.call(node, '.timeline-comment-wrapper')) { + node.classList.add('bountysource-comment-hide'); + } + } + commentsHidden++; + }; + + for (var i = 0, cL = comments.length; i < cL; i++) { + var comment = comments[i]; + var trimmedContent = comment.textContent.trim(); + + // Search for +1's + if (trimmedContent.length && /^\+1$/.test(trimmedContent)) { + hideTimelineWrapper(comment); + } + + // Search for thumbs up emoji + else if(!trimmedContent.length && comment.querySelectorAll("[alt=':+1:']").length) { + hideTimelineWrapper(comment); + } + + // Show event on timeline + if (commentsHidden && i === cL - 1) { + that.showEventOnTimeline(commentsHidden); + } + } + }; + + var hideThumbCb = function(msg) { + if(msg.hideThumbsup) + hideAll(); + else + that.showAllThumbs(); + }; + + // Get initial thumb prefs + BountysourceClient.message({action: 'get_hide_thumb_pref', callback: hideThumbCb}); + + // Listeners for pref change + if (BountysourceClient.browser === 'chrome') { + chrome.runtime.onMessage.addListener(function(options, sender, sendResponse) { + if(typeof options.hideThumbsup !== "undefined") { + hideThumbCb(options); + return true; + } + }); + } + else if (BountysourceClient.browser === 'firefox') { + self.port.on('hideThumbsup', hideThumbCb); + } + }; + + ThumbHide.prototype.showAllThumbs = function() { + var hiddenComments = [].slice.call(document.querySelectorAll('.bountysource-comment-hide')); + var btevent = document.querySelector('.bountysource-thumbsup-event'); + + for (var i = 0, hL = hiddenComments.length; i < hL; i++) { + hiddenComments[i].classList.remove('bountysource-comment-hide'); + } + + if(btevent) { + btevent.parentNode.removeChild(btevent); + } + }; + + ThumbHide.prototype.showEventOnTimeline = function(count) { + if (document.querySelector('.bountysource-thumbsup-event')) return; + + var hideThumbEventHTML = '\ +
\ + \ + Bountysource hid ${count} comments containing just :thumbsup: or +1 \ +
'; + var firstTimelineComment = document.querySelector(".timeline-comment-wrapper"); + var discussionEvent = document.createElement('div'); + + discussionEvent.className = 'discussion-item bountysource-thumbsup-event'; + discussionEvent.innerHTML = hideThumbEventHTML.replace('${count}', count); + + if (firstTimelineComment.nextElementSibling) { + firstTimelineComment.parentNode.insertBefore(discussionEvent, firstTimelineComment.nextElementSibling); + } + else { + firstTimelineComment.parentNode.appendChild(discussionEvent); + } + }; var matches; @@ -172,6 +269,10 @@ ThumbBox.loadAllData([box]); BountysourceClient.google_analytics({ path: "thumbs/github/show" }); } + + if (!document.querySelector('.bountysource-thumbsup-event')) { + new ThumbHide(); + } } else if (previousGithubUrl.match(/^https:\/\/github\.com\/[^/]+\/[^/]+\/(?:issues|pulls|labels|milestones)/) && document.body.classList.contains('vis-public')) { var issues = document.querySelectorAll('.issue-title'); var boxes = []; diff --git a/lib/bountysource_server.js b/lib/bountysource_server.js index 39bc55d..0c2fc95 100644 --- a/lib/bountysource_server.js +++ b/lib/bountysource_server.js @@ -26,11 +26,23 @@ var BountysourceServer = { if (BountysourceServer.browser === 'chrome') { chrome.runtime.onMessage.addListener(function(options, sender, sendResponse) { - BountysourceServer.get_access_token(function(access_token) { - options.access_token = access_token; - options.callback = sendResponse; - BountysourceServer[options.action](options); - }); + if (options.action === "get_hide_thumb_pref") { + chrome.storage.sync.get("hideThumbsup", sendResponse); + + chrome.storage.onChanged.addListener(function(changes) { + for (key in changes) { + if (key === "hideThumbsup") + chrome.tabs.sendMessage(sender.tab.id, { "hideThumbsup": changes[key].newValue }); + } + }); + } + else { + BountysourceServer.get_access_token(function(access_token) { + options.access_token = access_token; + options.callback = sendResponse; + BountysourceServer[options.action](options); + }); + } // always return true so the message doesn't keep getting passed return true; @@ -50,18 +62,29 @@ var BountysourceServer = { // receive message from BountysourceClient onAttach: function(worker) { - worker.port.on("message", function(options) { - BountysourceServer.get_access_token(function(access_token) { - options.access_token = access_token; - - // turn callback_str into function - options.callback = function(response) { - worker.port.emit(options.callback_str, response); - }; + var thumbPrefCb = function() { + worker.port.emit("hideThumbsup" , {hideThumbsup: require('sdk/simple-prefs').prefs['hideThumbsup']}); + }; - BountysourceServer[options.action](options); - }); + worker.port.on("message", function(options) { + if (options.action === "get_hide_thumb_pref") { + thumbPrefCb(); + } + else { + BountysourceServer.get_access_token(function(access_token) { + options.access_token = access_token; + + // turn callback_str into function + options.callback = function(response) { + worker.port.emit(options.callback_str, response); + }; + + BountysourceServer[options.action](options); + }); + } }); + + require("sdk/simple-prefs").on("hideThumbsup", thumbPrefCb); } }); } diff --git a/manifest.json b/manifest.json index 4e1bb5c..bbd1ded 100644 --- a/manifest.json +++ b/manifest.json @@ -16,7 +16,7 @@ }, "manifest_version": 2, "name": "Bountysource", - "permissions": [ "tabs", "cookies", "https://www.bountysource.com/*" ], + "permissions": [ "tabs", "cookies", "https://www.bountysource.com/*", "storage"], "web_accessible_resources": [ "data/images/thumbsup-20.png", "data/images/thumbsup-32.png", @@ -29,5 +29,6 @@ "browser_action": { "default_icon": "data/images/thumbsup-32.png", "default_popup": "data/popup/application.html" - } + }, + "options_page": "data/settings/options.html" } diff --git a/package.json b/package.json index 710f190..944b7c6 100644 --- a/package.json +++ b/package.json @@ -6,5 +6,12 @@ "version": "0.0.13", "author": "Bountysource Inc.", "main": "./lib/bountysource_server.js", - "license": "BSD" + "license": "BSD", + "preferences": [{ + "name": "hideThumbsup", + "title": "Thumbs up/+1", + "description": "Hide all comments with just :thumbsup: or +1", + "type": "bool", + "value": true + }] }