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
49 changes: 8 additions & 41 deletions source/features/add-branch-buttons.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,10 @@ import {h} from 'dom-chef';
import select from 'select-dom';
import compareVersions from 'tiny-version-compare';
import * as icons from '../libs/icons';
import * as cache from '../libs/cache';
import {appendBefore} from '../libs/utils';
import {groupSiblings} from '../libs/group-buttons';
import {getRepoURL, isRepoRoot, getOwnerAndRepo} from '../libs/page-detect';

// This regex should match all of these combinations:
// "This branch is even with master."
// "This branch is 1 commit behind master."
// "This branch is 1 commit ahead of master."
// "This branch is 1 commit ahead, 27 commits behind master."
const branchInfoRegex = /([^ ]+)\.$/;
import getDefaultBranch from '../libs/get-default-branch';
import {getRepoURL, isRepoRoot} from '../libs/page-detect';

function getTagLink() {
const tags = select
Expand Down Expand Up @@ -45,46 +38,20 @@ function getTagLink() {
return link;
}

async function getDefaultBranchNameIfDifferent() {
const {ownerName, repoName} = getOwnerAndRepo();
const cacheKey = `default-branch:${ownerName}/${repoName}`;

// Return the cached name if it differs from the current one
const cachedName = await cache.get(cacheKey);
if (cachedName) {
const currentBranch = select('[data-hotkey="w"] span').textContent;
return cachedName === currentBranch ? false : cachedName;
}

// We can find the name in the infobar, available in folder views
const branchInfo = select('.branch-infobar');
if (!branchInfo) {
return;
}

// Parse the infobar
const [, branchName] = branchInfo.textContent.trim().match(branchInfoRegex) || [];
if (branchName) {
cache.set(cacheKey, branchName, 1);
return branchName;
}
}

async function getDefaultBranchLink() {
if (select.exists('.repohead h1 .octicon-repo-forked')) {
return; // It's a fork, no "default branch" info available #1132
}
const defaultBranch = await getDefaultBranch();
const currentBranch = select('[data-hotkey="w"] span').textContent;

const branchName = await getDefaultBranchNameIfDifferent();
if (!branchName) {
// Don't show the button if we’re already on the default branch
if (defaultBranch === currentBranch) {
return;
}

let url;
if (isRepoRoot()) {
url = `/${getRepoURL()}`;
} else {
const branchLink = select(`.select-menu-item[data-name='${branchName}']`);
const branchLink = select(`.select-menu-item[data-name='${defaultBranch}']`);
if (!branchLink) {
return;
}
Expand All @@ -98,7 +65,7 @@ async function getDefaultBranchLink() {
aria-label="Visit the default branch">
{icons.branch()}
{' '}
{branchName}
{defaultBranch}
</a>
);
}
Expand Down
22 changes: 13 additions & 9 deletions source/libs/cache.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
export default async function getSet(key, getter, expiration) {
export async function getSet(key, getter, expiration) {
const cache = await get(key);
if (cache === undefined) {
const value = getter();
if (value !== undefined) {
await set(key, value, expiration);
return value;
}
if (cache !== undefined) {
return cache;
}
const value = await getter();
if (value !== undefined) {
await set(key, value, expiration);
return value;
}
}

Expand All @@ -16,7 +17,7 @@ export async function get(key) {
});

// If it's not in the cache, it's best to return "undefined"
if (value === null) {
if (value === null || value === undefined) {
return undefined;
}
return value;
Expand All @@ -41,14 +42,17 @@ if (!browser.runtime.getBackground) {
if (code === 'get-cache') {
const [cached] = document.cookie.split('; ')
.filter(item => item.startsWith(key + '='));

if (cached) {
const [, value] = cached.split('=');
sendResponse(JSON.parse(value));
console.log('CACHE: found', key, value);
} else {
sendResponse();
console.log('CACHE: not found', key);
}
} else if (code === 'set-cache') {
console.log('CACHE: setting', key, value);

// Store as JSON to preserve data type
// otherwise Booleans and Numbers become strings
document.cookie = `${key}=${JSON.stringify(value)}; max-age=${expiration ? expiration * 3600 * 24 : ''}`;
Expand Down
41 changes: 41 additions & 0 deletions source/libs/get-default-branch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import select from 'select-dom';
import * as cache from './cache';
import * as api from './api';
import {getOwnerAndRepo} from './page-detect';

// This regex should match all of these combinations:
// "This branch is even with master."
// "This branch is 1 commit behind master."
// "This branch is 1 commit ahead of master."
// "This branch is 1 commit ahead, 27 commits behind master."
const branchInfoRegex = /([^ ]+)\.$/;

function parseBranchFromDom() {
if (select.exists('.repohead h1 .octicon-repo-forked')) {
return; // It's a fork, no "default branch" info available #1132
}

// We can find the name in the infobar, available in folder views
const branchInfo = select('.branch-infobar');
if (!branchInfo) {
return;
}

// Parse the infobar
const [, branchName] = branchInfo.textContent.trim().match(branchInfoRegex) || [];
return branchName; // `string` or undefined
}

async function fetchFromApi(user, repo) {
const response = await api.v3(`repos/${user}/${repo}`);
if (response && response.default_branch) {
return response.default_branch;
}
}

export default function () {
const {ownerName, repoName} = getOwnerAndRepo();
return cache.getSet(`default-branch:${ownerName}/${repoName}`,
() => parseBranchFromDom() || fetchFromApi(ownerName, repoName)
);
}