Skip to content

Commit 6175a60

Browse files
committed
.
0 parents  commit 6175a60

14 files changed

+373
-0
lines changed

.bowerrc

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"directory": "components"
3+
}

.gitignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
*.iml
2+
.DS_Store
3+
build.crx
4+
build/
5+
components/
6+
github-punchcard.zip
7+
node_modules/
8+
punchcard.svg

.web-extension-id

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# This file was created by https://github.com/mozilla/web-ext
2+
# Your auto-generated extension ID for addons.mozilla.org is:
3+
4+
#{196557c8-dd56-46f2-b999-8d7cdd784781}

README.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
https://www.reddit.com/r/github/comments/768oqr/is_the_punchcard_graph_gone_now/
2+
* https://issarice.com/github-punch-card-exploration
3+
4+
https://github.com/blog/1093-introducing-the-new-github-graphs
5+
6+
https://github.com/guanqun/git-punchcard-plot
7+
8+
TODO https://docs.microsoft.com/en-us/microsoft-edge/extensions

build.sh

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/env bash
2+
pushd $(dirname $0)
3+
4+
# TODO migrate to npm
5+
bower i
6+
7+
mkdir -p build
8+
9+
# meta
10+
cp src/manifest.json build/
11+
cp src/icon.png build/
12+
cp src/background.js build/
13+
cp src/content.js build/
14+
cp components/github-punchcard/PunchCard.js build/
15+
16+
# options page
17+
# https://github.com/PolymerLabs/crisper#usage-with-vulcanize
18+
vulcanize options.html --inline-script | crisper --html build/options.html --js build/options.js
19+
20+
# test page
21+
vulcanize test.html --inline-script | crisper --html build/test.html --js build/test.js
22+
cp components/jasmine-core/images/jasmine_favicon.png build/
23+
cp components/jasmine-core/lib/jasmine-core/jasmine.css build/
24+
sed -i "" s~components/jasmine-core/images/~~g build/test.html
25+
sed -i "" s~components/jasmine-core/lib/jasmine-core/~~g build/test.html
26+
27+
rm github-punchcard.zip
28+
pushd build
29+
zip ../github-punchcard.zip *
30+
popd
31+
32+
popd

github-mark.png

23.4 KB
Loading

options.html

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
6+
7+
<title>Github Punchcard</title>
8+
<meta name="description" content="Github Punchcard">
9+
10+
<!-- See https://goo.gl/OOhYW5 -->
11+
<link rel="manifest" href="manifest.json">
12+
13+
<!-- See https://goo.gl/qRE0vM -->
14+
<meta name="theme-color" content="#3f51b5">
15+
16+
<!-- Add to homescreen for Chrome on Android. Fallback for manifest.json -->
17+
<meta name="mobile-web-app-capable" content="yes">
18+
<meta name="application-name" content="Github Punchcard">
19+
20+
<!-- Add to homescreen for Safari on iOS -->
21+
<meta name="apple-mobile-web-app-capable" content="yes">
22+
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
23+
<meta name="apple-mobile-web-app-title" content="Github Punchcard">
24+
25+
<!-- Load webcomponents-loader.js to check and load any polyfills your browser needs -->
26+
<!-- webcomponents-loader.js doesn't work with vulcanize -->
27+
<!--<script src="components/webcomponentsjs/webcomponents-loader.js"></script>-->
28+
<!-- https://github.com/webcomponents/webcomponentsjs#how-to-use -->
29+
<script src="components/webcomponentsjs/webcomponents-lite.js"></script>
30+
31+
<!-- Load your application shell -->
32+
<link rel="import" href="components/polymer/lib/elements/dom-bind.html">
33+
<link rel="import" href="components/paper-input/paper-input.html"/>
34+
<link rel="import" href="components/github-punchcard/github-punchcard.html">
35+
36+
</head>
37+
<body>
38+
<!-- https://www.polymer-project.org/2.0/docs/devguide/templates#dom-bind -->
39+
<dom-bind>
40+
<template>
41+
<paper-input label="User" value="{{user}}"></paper-input>
42+
<paper-input label="Repo" value="{{repo}}"></paper-input>
43+
<github-punchcard user="{{user}}" repo="{{repo}}"></github-punchcard>
44+
</template>
45+
</dom-bind>
46+
<!--<script>
47+
var autobind = document.querySelector('dom-bind');
48+
autobind.setProperties({
49+
user: "polymer",
50+
repo: "polymer",
51+
});
52+
</script>-->
53+
</body>
54+
</html>

screenshot-1280x800.png

21.1 KB
Loading

src/background.js

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
chrome.browserAction.onClicked.addListener(function(activeTab) {
2+
/*
3+
* https://stackoverflow.com/questions/6782391/programmatically-open-a-chrome-plugins-options-html-page
4+
*/
5+
chrome.runtime.openOptionsPage();
6+
});
7+
8+
var urlPattern1 = new RegExp("https://github.com/([^/]+)/([^/]+)/(pulse|graphs/contributors|community|graphs/traffic|graphs/commit-activity|graphs/code-frequency|network/dependencies|network|network/members)");
9+
var urlPattern2 = new RegExp("https://github.com/([^/]+)/([^/]+)/graphs/punchcard");
10+
11+
/*
12+
* https://stackoverflow.com/questions/2149917/chrome-extensions-how-to-know-when-a-tab-has-finished-loading-from-the-backgr
13+
*/
14+
chrome.tabs.onUpdated.addListener(function(tabId, info) {
15+
console.log(tabId);
16+
console.log(info);
17+
chrome.tabs.get(tabId, function(tab) {
18+
var g = tab.url.match(urlPattern1);
19+
if (g) {
20+
chrome.tabs.sendMessage(tabId, {
21+
user: g[1],
22+
repo: g[2],
23+
page: g[3],
24+
});
25+
} else {
26+
g = tab.url.match(urlPattern2);
27+
if (g) {
28+
/*
29+
* https://stackoverflow.com/questions/26119027/chrome-extension-stop-loading-the-page-on-launch
30+
*/
31+
chrome.tabs.executeScript(tabId, {
32+
code: "window.stop();",
33+
runAt: "document_start"
34+
});
35+
chrome.tabs.sendMessage(tabId, {
36+
user: g[1],
37+
repo: g[2],
38+
});
39+
}
40+
}
41+
});
42+
});
43+
44+
//chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
45+
// console.log("message received by background");
46+
// sendResponse();
47+
//// return true;
48+
//});

src/content.js

+156
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/*
2+
* https://stackoverflow.com/questions/17377337/where-to-find-extensions-installed-folder-for-google-chrome-on-mac
3+
*/
4+
5+
//"https://github.com/*/*/pulse",
6+
//"https://github.com/*/*/graphs/contributors",
7+
//"https://github.com/*/*/community",
8+
//"https://github.com/*/*/graphs/traffic",
9+
//"https://github.com/*/*/graphs/commit-activity",
10+
//"https://github.com/*/*/graphs/code-frequency",
11+
//"https://github.com/*/*/network/dependencies",
12+
//"https://github.com/*/*/network",
13+
//"https://github.com/*/*/network/members"
14+
15+
function inject(user, repo) {
16+
var c = document.querySelector("div.column.three-fourths");
17+
console.log(c);
18+
19+
/*
20+
* the name self is borrowed from the web component (github-punchcard.html), and has nothing special here
21+
*/
22+
var self = {
23+
weekDay: function(index) {
24+
return ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][index];
25+
},
26+
r: function(hour) {
27+
return Math.sqrt(hour);
28+
},
29+
d: function(hour) {
30+
return Math.ceil(this.r(hour) * 2);
31+
},
32+
};
33+
new PunchCard().load(user, repo).then(function(punchCard) {
34+
console.log(punchCard);
35+
self.punchCard = punchCard;
36+
37+
self.width = 25;
38+
self.height = 25;
39+
for (var day of punchCard) {
40+
for (var hour of day) {
41+
var d = self.d(hour);
42+
if (self.height < d) {
43+
self.height = d;
44+
}
45+
if (self.width < d) {
46+
self.width = d;
47+
}
48+
}
49+
}
50+
51+
/*
52+
* TODO make it look more like the original graph
53+
*/
54+
var t = document.createElement("table");
55+
for (var d in punchCard) {
56+
var day = punchCard[d];
57+
var r = document.createElement("tr");
58+
59+
var h = document.createElement("th");
60+
h.innerText = self.weekDay(d);
61+
h.style = "text-align: right;";
62+
r.appendChild(h);
63+
64+
for (var hour of day) {
65+
var d = document.createElement("td");
66+
d.style = "width: " + self.width + "px; height: " + self.height + "px;";
67+
r.appendChild(d);
68+
69+
var v = document.createElement("div");
70+
v.style = "margin: auto; background-color: black; border-radius: 50%; width: " + self.d(hour) + "px; height: " + self.d(hour) + "px;";
71+
d.appendChild(v);
72+
}
73+
74+
t.appendChild(r);
75+
}
76+
77+
var r = document.createElement("tr");
78+
79+
var h = document.createElement("th");
80+
r.appendChild(h);
81+
for (var i = 0; i < 24; i++) {
82+
h = document.createElement("th");
83+
h.innerText = i;
84+
r.appendChild(h);
85+
}
86+
t.appendChild(r);
87+
88+
/*
89+
* https://stackoverflow.com/questions/3955229/remove-all-child-elements-of-a-dom-node-in-javascript
90+
*/
91+
while (c.firstChild) {
92+
c.removeChild(c.firstChild);
93+
}
94+
c.appendChild(t);
95+
}).catch(function(e) {
96+
console.log(e);
97+
});
98+
}
99+
100+
//var documentClone;
101+
102+
chrome.runtime.onMessage.addListener(function(message, sender, sendResponseCallback) {
103+
console.log("message received");
104+
105+
if (message.page) {
106+
var x = document.evaluate("//a[text()='Punchcard']", document, null, XPathResult.ANY_TYPE, null);
107+
if (x.iterateNext()) {
108+
return;
109+
}
110+
111+
/*
112+
* https://stackoverflow.com/questions/37098405/javascript-queryselector-find-div-by-innertext
113+
*/
114+
x = document.evaluate("//a[text()='Code frequency']", document, null, XPathResult.ANY_TYPE, null);
115+
var a = x.iterateNext();
116+
117+
var b = a.cloneNode();
118+
b.innerText = "Punchcard";
119+
b.href = a.href.replace("code-frequency", "punchcard");
120+
b.setAttribute("data-selected-links", a.getAttribute("data-selected-links").replace("code-frequency", "punchcard"));
121+
122+
/*
123+
* https://stackoverflow.com/questions/2155737/remove-css-class-from-element-with-javascript-no-jquery
124+
*/
125+
b.classList.remove("selected");
126+
127+
b.onclick = function() {
128+
//documentClone = document.cloneNode(true);
129+
130+
a = document.querySelector("a[href='/" + message.user + "/" + message.repo + "/" + message.page + "']");
131+
a.classList.remove("selected");
132+
133+
b.classList.add("selected");
134+
135+
try {
136+
inject(message.user, message.repo);
137+
} finally {
138+
return false;
139+
}
140+
}
141+
a.parentElement.insertBefore(b, a);
142+
} else {
143+
//console.log(documentClone);
144+
inject(message.user, message.repo);
145+
}
146+
147+
//return true;
148+
});
149+
150+
//chrome.runtime.sendMessage({}, function(response) {
151+
// if (response) {
152+
// console.log(response);
153+
// } else if (chrome.runtime.lastError) {
154+
// console.log(chrome.runtime.lastError);
155+
// }
156+
//});

src/favicon.ico

6.37 KB
Binary file not shown.

src/icon.png

4.9 KB
Loading

src/manifest.json

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"manifest_version": 2,
3+
"name": "Github Punchcard",
4+
"version": "0.2",
5+
"description": "Restores Github Punchcard graph",
6+
"background": {
7+
"scripts": [
8+
"background.js"
9+
]
10+
},
11+
"browser_action": {
12+
"default_icon": "icon.png",
13+
"default_title": "Github Punchcard"
14+
},
15+
"options_ui": {
16+
"page": "options.html",
17+
"chrome_style": true,
18+
"open_in_tab": true
19+
},
20+
"permissions": [
21+
"tabs",
22+
"https://api.github.com/*",
23+
"https://github.com/*"
24+
],
25+
"content_scripts": [
26+
{
27+
"js": [
28+
"content.js",
29+
"PunchCard.js"
30+
],
31+
"matches": [
32+
"https://github.com/*"
33+
]
34+
}
35+
]
36+
}

test.html

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Github Punchcard</title>
6+
7+
<link rel="shortcut icon" type="image/png" href="components/jasmine-core/images/jasmine_favicon.png">
8+
<link rel="stylesheet" href="components/jasmine-core/lib/jasmine-core/jasmine.css">
9+
10+
<script src="components/jasmine-core/lib/jasmine-core/jasmine.js"></script>
11+
<script src="components/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
12+
<script src="components/jasmine-core/lib/jasmine-core/boot.js"></script>
13+
14+
<!-- include source files here... -->
15+
<script src="components/github-punchcard/PunchCard.js"></script>
16+
17+
<!-- include spec files here... -->
18+
<script src="components/github-punchcard/PunchCardSpec.js"></script>
19+
20+
</head>
21+
22+
<body>
23+
</body>
24+
</html>

0 commit comments

Comments
 (0)