Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# GitHub +1 Chrome Extension

![GitHub +1 Chrome Extension](http://i.imgur.com/wJLc7R4.png)

More information and installation instructions can be found on the Chrome Web Store.

[![Available in the Chrome Web Store](https://developer.chrome.com/webstore/images/ChromeWebStore_BadgeWBorder_v2_206x58.png)](https://chrome.google.com/webstore/detail/github-%201s/lddfkkebajnpiicnpfamebilmhamkeme)

# Github Enterprise support

* Open GitHub +1 options panel from [chrome://extensions](chrome://extensions)
* Add location to your GitHub Enterprise
* Accept new permission
13 changes: 13 additions & 0 deletions background.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (changeInfo.status !== 'loading') return

chrome.tabs.executeScript(tabId, {
file : 'content_script.js',
runAt : 'document_end'
}, function(res) {
if (chrome.runtime.lastError || // don't continue if error (i.e. page isn't in permission list)
res[0]) { // value of `injected` above: don't inject twice
return;
}
})
})
46 changes: 32 additions & 14 deletions content_script.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,21 @@ function buildVoteIcons() {
var alreadySeenDown = [];

function findUpVoter(comment) {
findVoter('+1', comment, upAvatars, alreadySeenUp);
findVoter('+1', 'thumbsup', comment, upAvatars, alreadySeenUp);
}

function findDownVoter(comment) {
findVoter('-1', comment, downAvatars, alreadySeenDown);
findVoter('-1', 'thumbsdown', comment, downAvatars, alreadySeenDown);
}

function findVoter(voteText, comment, avatars, alreadySeen) {
function findVoter(voteText, voteText2, comment, avatars, alreadySeen) {
var regex = new RegExp('^\\' + voteText);
var text = comment.querySelector('.comment-body').textContent.trim();
if (text.match(regex) || comment.querySelector('img[title=":' + voteText + ':"]')) {
if (
text.match(regex) ||
comment.querySelector('img[title=":' + voteText + ':"]') ||
comment.querySelector('img[title=":' + voteText2 + ':"]')
) {
var avatar = comment.querySelector('a').cloneNode(true);
var user = avatar.href;
if (alreadySeen.indexOf(user) < 0) {
Expand All @@ -33,29 +37,32 @@ function buildVoteIcons() {
function appendVotes(avatars, icon) {
if (avatars.length > 0) {
var div = document.createElement('div');
div.className = 'flex-table gh-header-meta';
div.className = 'js-' + (icon=='thumbsup' ? 'plus' : 'minus') + '-one-count flex-table gh-header-meta';
div.innerHTML = ''+
'<div class="flex-table-item">'+
' <div class="state" style="background: hsl(215, 50%, 50%)">'+
' <span class="octicon octicon-' + icon + '"></span>'+
avatars.length+
' ' + (icon=='thumbsup' ? '+' : '-') + avatars.length +
' </div>'+
'</div>'+
'<div class="flex-table-item flex-table-item-primary"></div>';

var avatarContainer = div.querySelector('.flex-table-item-primary');
avatarContainer.style.paddingTop = 0;

avatars.forEach(function(avatar) {
avatar.className = 'tooltipped tooltipped-' + (icon=='thumbsup' ? 'n' : 's');
avatar.style.float = 'left';
var img = avatar.querySelector('img');
img.className = '';
img.style.height = '26px';
img.style.width = '26px';
img.style.margin = '0 2px';
img.style.borderRadius = '3px';
avatar.setAttribute('aria-label', img.alt.substring(1));
img.className = 'avatar avatar-small';
img.setAttribute('height', '26px');
img.setAttribute('width', '26px');
avatarContainer.appendChild(avatar);
});

var currentCount = document.querySelector('.js-' + (icon=='thumbsup' ? 'plus' : 'minus') + '-one-count');
if (currentCount) { currentCount.remove(); }

document.querySelector('.gh-header-show').appendChild(div);
}
}
Expand All @@ -69,8 +76,19 @@ function buildVoteIcons() {
appendVotes(downAvatars, 'thumbsdown');
}

var observer = new MutationObserver(function() {
buildVoteIcons();
var observer = new MutationObserver(function(mutations) {
var needsRemoval = false;
mutations.forEach(function(mutation) {
Array.prototype.slice.call(mutation.addedNodes).forEach(function(node) {
if (node instanceof Element && (node.querySelector('.js-comment') || node.classList.contains('js-comment'))) {
needsRemoval = true;
}
});
});

if (needsRemoval) {
buildVoteIcons();
}
});

observer.observe(document.querySelector('div.js-discussion'), {childList: true});
Expand Down
22 changes: 14 additions & 8 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
{
"name": "Github +1s",
"description": "Shows you the counts and avatars of those noisy '+1' comments and hides the original comments.",
"version": "1.2.0",
"version": "1.4.0",
"permissions": [
"activeTab"
"https://github.com/*",
"storage"
],
"optional_permissions": [
"<all_urls>"
],
"icons": {
"128": "plusone.png"
},
"manifest_version": 2,
"content_scripts": [
{
"matches": ["https://github.com/*"],
"js": ["content_script.js"]
}
]
"options_ui": {
"page": "options.html",
"chrome_style": true
},
"background": {
"scripts": [ "background.js" ],
"persistent": false
}
}
17 changes: 17 additions & 0 deletions options.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head>
<title>GitHub +1s Options</title>
</head>
<body>
<label>
GitHub Enterprise Url: <input id='gh_url'>
</label>

<div id="status"></div>
<div id="error"></div>

<button id="save">Save</button>
<script src="options.js"></script>
</body>
</html>
38 changes: 38 additions & 0 deletions options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Saves options to chrome.storage
function save_options() {
var gh_url = document.getElementById('gh_url').value;
chrome.permissions.request({
origins: [gh_url]
}, function(granted) {
if (!granted) {
var error = document.getElementById('error');
error.textContent = 'Url format: <protocol>://<domain>.<tld>/';
}
});

chrome.storage.sync.set({
gh_url: gh_url
}, function() {
// Update status to let user know options were saved.
var status = document.getElementById('status');
status.textContent = 'Options saved.';
setTimeout(function() {
status.textContent = '';
}, 750);
});
}

// Restores select box and checkbox state using the preferences
// stored in chrome.storage.
function restore_options() {
chrome.storage.sync.get({
gh_url: ''
}, function(items) {
document.getElementById('gh_url').value = items.gh_url;
});
}

document.addEventListener('DOMContentLoaded', restore_options);
document.getElementById('save').addEventListener('click',
save_options);