diff --git a/css/templates/github.css b/css/templates/github.css new file mode 100644 index 0000000..e90b73a --- /dev/null +++ b/css/templates/github.css @@ -0,0 +1,103 @@ +.survol-github-container { + padding: 15px; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, + sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + width: auto; + height: auto; +} + +#survol-github-avatar{ + display: inline-block; + vertical-align: top; + margin-right: 10px; + border-radius : 50%; +} + +#survol-github-user-info { + width: auto; + max-width : 280px; + text-decoration: inherit; + color: inherit; + } + + .survol-github-name { + font-weight: 600; + font-size: 20px; + } + + .survol-github-at { + display: block; + font-size: 16px; + color: #666; + font-style: normal; + font-weight: 400; + margin-bottom: 5px; + } + + .dark-theme .survol-github-at { + color: #aab3be; + } + + .survol-github-bio { + font-size: 13px; + color: #6a737d; + } + + .dark-theme .survol-github-bio { + color: #aab3be; + } + +.survol-github-profile-stats { + display: block; + margin-top: 8px; + text-align: center; + min-width:330px; + } + + .survol-github-profile-stat { + text-decoration: none; + width: 30%; + border-right: 1px solid #eaecef; + color: #586069; + display: inline-block; + margin-top: 5px; + margin-bottom: 8px; + } + + .dark-theme .survol-github-profile-stat span, .dark-theme .survol-github-profile-stat b { + color: #eaecef; + } + + + .survol-github-profile-stat:last-of-type { + border-right: none; + } + + + .survol-github-prof-stat-val { + font-size: 19px; + text-align: center; + display: block; + } + .survol-github-prof-stat-name { + font-size: 11px; + text-align: center; + display: block; + } + + .survol-github-links{ + display: inline-block; + vertical-align: top; + } + + .survol-github-link{ + display: inline; + font-size: 15; + font-weight : 400; +} + +.empty{ + opacity : 35%; + font-weight : 100; + font-style : italic; +} diff --git a/js/core.js b/js/core.js index 6b04c44..5256c62 100644 --- a/js/core.js +++ b/js/core.js @@ -161,6 +161,8 @@ document.addEventListener('DOMContentLoaded', () => { return new StackExchangeHover(node, getDomain(CURRENT_TAB)); case 'soundcloud.com': return new SoundCloudHover(node, getDomain(CURRENT_TAB)); + case 'github.com': + return new GitHubHover(node, getDomain(CURRENT_TAB)); // If the site has no custom template, it should be previewed using meta-data parsing default: diff --git a/js/templates/github.js b/js/templates/github.js new file mode 100644 index 0000000..698d7d9 --- /dev/null +++ b/js/templates/github.js @@ -0,0 +1,142 @@ +/* Hover classes bound themselves to a node + */ +class GitHubHover { + constructor(node, CURRENT_TAB) { + this.boundNode = node; + this.redirectLink = node.href; + this.CURRENT_TAB = CURRENT_TAB; + this.linkType = this.checkLinkType(); + this.parser = new DOMParser(); + } + + checkLinkType() { + if (this.CURRENT_TAB == 'github.com' || this.redirectLink.match(/(github.com)\/[\w]{1,256}\/[\w]{1,256}\/[\w]/g)) return 'unknown'; + else if (this.redirectLink.match(/(github.com)\/[\w]{1,256}\/[\w]{1,256}/g)) return 'repo'; + else return 'profile'; + } + + /* bindToContainer + * Parameters : + * node - {HTMLNodeElement} - An anchor link element + * domain - {String} - The domain of the current webpage + * container - {HTMLNodeElement} - The survol container + * + * This function is called to get the data from the link we + * want to preview and then attach it to the container + * Note: data is always inserted into textNodes to avoid + * malicious script injections. + */ + bindToContainer(node, domain, container) { + if (this.linkType == 'profile') { + + const username = this.redirectLink.split('github.com/')[1]; + + window + .survolBackgroundRequest(`https://api.github.com/users/${username}`) + .then(({ data }) => { + + let githubContainer = document.createElement('div'); + githubContainer.className = 'survol-github-container'; + + let githubProfileContainer = document.createElement('div'); + githubProfileContainer.id = 'survol-github-profile'; + + let profilePic = document.createElement('img'); + profilePic.id = 'survol-github-avatar'; + profilePic.src = data.avatar_url; + profilePic.style.width = '80px'; + githubProfileContainer.appendChild(profilePic); + + let profInfo = document.createElement('div'); + profInfo.id = 'survol-github-user-info'; + + profInfo.style = 'display: inline-block'; + + let name = document.createElement('span'); + name.className = 'survol-github-name'; + name.appendChild(document.createTextNode(data.name || data.login)); + + let githubAt = document.createElement('span'); + githubAt.className = 'survol-github-at'; + githubAt.appendChild(document.createTextNode(` @${data.login}`)); + + let bio = document.createElement('span'); + bio.className = 'survol-github-bio'; + bio.appendChild(document.createTextNode(data.bio ? data.bio : '')); + + profInfo.appendChild(name); + profInfo.appendChild(githubAt); + profInfo.appendChild(bio); + + githubProfileContainer.appendChild(profInfo); + + let profStats = document.createElement('div'); + profStats.className = 'survol-github-profile-stats'; + + let statdata = [{ 'name': 'Repos', 'stat': data.public_repos }, + { 'name': 'Followers', 'stat': data.followers }, + { 'name': 'Following', 'stat': data.following }]; + + statdata.forEach((x) => { + let stat = document.createElement('a'); + stat.className = 'survol-github-profile-stat'; + + let statNumber = document.createElement('b'); + statNumber.className = 'survol-github-prof-stat-val'; + statNumber.appendChild(document.createTextNode(x.stat)); + let statName = document.createElement('span'); + statName.className = 'survol-github-prof-stat-name'; + statName.appendChild(document.createTextNode(x.name)); + + stat.appendChild(statNumber); + stat.appendChild(statName); + + profStats.appendChild(stat); + }); + + + githubProfileContainer.appendChild(profStats); + + let githubLinksContainer = document.createElement('div'); + githubLinksContainer.className = 'survol-github-links'; + + let links = [{ 'name': 'Workplace: ', 'link': data.company ? data.company : 'not available' }, + { 'name': 'Twitter: ', 'link': data.twitter_username ? '@' + data.twitter_username : 'not available' }, + { 'name': 'Website: ', 'link': data.blog ? data.blog : 'not available' }]; + + links.forEach((link) => { + let linkContainer = document.createElement('div'); + + let linkName = document.createElement('span'); + linkName.appendChild(document.createTextNode(link.name)); + linkName.className = 'survol-github-link'; + + linkContainer.appendChild(linkName); + + let linkText = document.createElement('span'); + linkText.appendChild(document.createTextNode(link.link)); + + if (link.link.includes('not available')) { + linkText.className = 'survol-github-link empty'; + } else { + linkText.className = 'survol-github-link'; + } + + linkContainer.appendChild(linkText); + + githubLinksContainer.appendChild(linkContainer); + }) + + githubProfileContainer.appendChild(githubLinksContainer); + + githubContainer.appendChild(githubProfileContainer); + + if (window.lastHovered == node && container.innerHTML == '') { + container.appendChild(githubContainer); + } + }) + .catch(console.error); + + } + } +} \ No newline at end of file diff --git a/manifest.json b/manifest.json index 062fc3a..2820456 100644 --- a/manifest.json +++ b/manifest.json @@ -1,6 +1,6 @@ { "manifest_version": 2, - "version": "0.6.0", + "version": "0.6.2", "name": "__MSG_extensionName__", "short_name": "__MSG_extensionShortName__", "description": "__MSG_extensionDescription__", @@ -33,6 +33,7 @@ "js/templates/youtube.js", "js/templates/stackexchange.js", "js/templates/soundcloud.js", + "js/templates/github.js", "js/core.js" ], @@ -43,7 +44,8 @@ "css/templates/twitter.css", "css/templates/youtube.css", "css/templates/stackexchange.css", - "css/templates/soundcloud.css" + "css/templates/soundcloud.css", + "css/templates/github.css" ], "run_at": "document_start"