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 = '\
+ ';
+ 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
+ }]
}