Skip to content

Commit

Permalink
Merge branch 'main' into ft/small-style-adjustements
Browse files Browse the repository at this point in the history
  • Loading branch information
filiptronicek authored Oct 2, 2023
2 parents 921e62b + ca6777d commit 925b504
Show file tree
Hide file tree
Showing 12 changed files with 213 additions and 24 deletions.
50 changes: 37 additions & 13 deletions .github/workflows/submit.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
name: "Submit to Web Store"
name: "Submit to Web Stores"
on:
workflow_dispatch:
push:
branches:
- master
inputs:
channel:
description: 'Release channel to publish to'
required: true
type: choice
options:
- staging
- production
default: staging

env:
CHANNEL: ${{ github.event.inputs.channel || 'staging' }}

jobs:
build:
Expand All @@ -21,17 +30,32 @@ jobs:
with:
version: latest
run_install: true
- name: Use Node.js 16.x
- name: Use Node.js 18.x
uses: actions/setup-node@v3.4.1
with:
node-version: 16.x
node-version: 18.x
cache: "pnpm"
- name: Build the extension
run: pnpm build
- name: Package the extension into a zip artifact
run: pnpm package
- name: Browser Platform Publish
- name: Build the extension (Chrome)
run: pnpm plasmo build --target=chrome-mv3
- name: Build the extension (Firefox)
run: pnpm plasmo build --target=firefox-mv2
- name: Package the extension into zip artifacts
run: |
pnpm package --target=chrome-mv3
pnpm package --target=firefox-mv2
- name: Browser Platform Publish (staging)
uses: PlasmoHQ/bpp@v3
if: env.CHANNEL == 'staging'
with:
keys: ${{ secrets.SUBMIT_KEYS_STAGING }}
verbose: true
chrome-file: build/chrome-mv3-prod.zip
firefox-file: build/firefox-mv2-prod.zip
- name: Browser Platform Publish (production)
uses: PlasmoHQ/bpp@v3
if: env.CHANNEL == 'production'
with:
keys: ${{ secrets.SUBMIT_KEYS }}
artifact: build/chrome-mv3-prod.zip
keys: ${{ secrets.SUBMIT_KEYS_PRODUCTION }}
verbose: true
chrome-file: build/chrome-mv3-prod.zip
firefox-file: build/firefox-mv2-prod.zip
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ dist/
.plasmo

# bpp - http://bpp.browser.market/
keys.json
key*.json

# typescript
.tsbuildinfo
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,4 @@
}
}
}
}
}
25 changes: 25 additions & 0 deletions src/button/button-contributions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,31 @@

export type SupportedApplication = "github" | "gitlab" | "bitbucket-server" | "bitbucket";

const resolveMetaAppName = (head: HTMLHeadElement): string | undefined => {
const metaApplication = head.querySelector("meta[name=application-name]");
const ogApplication = head.querySelector("meta[property='og:site_name']");

if (metaApplication) {
return metaApplication.getAttribute("content") || undefined;
} else if (ogApplication) {
return ogApplication.getAttribute("content") || undefined;
}

return undefined;
}

/**
* Provides a fast check to see if the current URL is on a supported site.
*/
export const isSiteSuitable = (): boolean => {
const appName = resolveMetaAppName(document.head);
if (!appName) {
return false;
}
const allowedApps = ["GitHub", "GitLab", "Bitbucket"];
return allowedApps.includes(appName);
}

export interface ButtonContributionParams {
/**
* A unique id for the button contribution. Used to identify the button in the UI.
Expand Down
5 changes: 3 additions & 2 deletions src/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Logo from "react:./logo-mark.svg"
import type { SupportedApplication } from "./button-contributions";
import classNames from "classnames";
import { STORAGE_KEY_ADDRESS, STORAGE_KEY_NEW_TAB } from "~storage";
import { DEFAULT_GITPOD_ENDPOINT } from "~constants";
import { useStorage } from "@plasmohq/storage/hook";
import React from "react";

Expand All @@ -12,8 +13,8 @@ export interface GitpodButtonProps {
}

export const GitpodButton = ({ application, additionalClassNames }: GitpodButtonProps) => {
const [address] = useStorage<string>(STORAGE_KEY_ADDRESS, "https://gitpod.io");
const [openInNewTab] = useStorage<boolean>(STORAGE_KEY_NEW_TAB, false);
const [address] = useStorage<string>(STORAGE_KEY_ADDRESS, DEFAULT_GITPOD_ENDPOINT);
const [openInNewTab] = useStorage<boolean>(STORAGE_KEY_NEW_TAB, true);

const [showDropdown, setShowDropdown] = useState(false);
const actions = [
Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const DEFAULT_GITPOD_ENDPOINT = "https://gitpod.io";
16 changes: 14 additions & 2 deletions src/contents/button.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { PlasmoCSConfig, PlasmoGetInlineAnchor } from "plasmo";
import cssText from "data-text:../button/button.css"
import { buttonContributions, type ButtonContributionParams } from "../button/button-contributions";
import { buttonContributions, type ButtonContributionParams, isSiteSuitable } from "../button/button-contributions";
import { GitpodButton } from "../button/button";
import { type ReactElement } from "react";
import React from "react";
Expand All @@ -23,7 +23,16 @@ class ButtonContributionManager {
anchor: HTMLElement,
}

_disabled = false;

constructor(private contributions: ButtonContributionParams[]) {
if (!this._disabled) {
const isSuitable = isSiteSuitable();
if (!isSuitable) {
this._disabled = true;
}
}

for (const contribution of this.contributions) {
const containerId = this.getContainerId(contribution);
if (!this.buttons.has(containerId)) {
Expand All @@ -47,6 +56,10 @@ class ButtonContributionManager {
}

public getInlineAnchor(): HTMLElement | null {
if (this._disabled) {
return null;
}

for (const contribution of this.contributions) {
const isActive = this.isActive(contribution);
if (isActive) {
Expand Down Expand Up @@ -84,7 +97,6 @@ class ButtonContributionManager {
} else if (typeof contrib.match === "object" && !contrib.match.test(window.location.href)) {
return false;
}

const parent = this.lookupElement(contrib.selector);
if (parent === null) {
return false;
Expand Down
37 changes: 37 additions & 0 deletions src/contents/gitpod-dashboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import type { PlasmoCSConfig } from "plasmo";
import { Storage } from "@plasmohq/storage";
import { STORAGE_AUTOMATICALLY_DETECT_GITPOD, STORAGE_KEY_ADDRESS } from "~storage";
import { parseEndpoint } from "~utils/parse-endpoint";
import { DEFAULT_GITPOD_ENDPOINT } from "~constants";

/**
* Checks if the current site is a Gitpod instance.
*/
const isSiteGitpod = (): boolean => {
return !!document.head.querySelector("meta[name=Gitpod]");
}

export const config: PlasmoCSConfig = {
matches: ["https://*/*"]
}

const storage = new Storage();

const automaticallyUpdateEndpoint = async () => {
if (await storage.get<boolean>(STORAGE_AUTOMATICALLY_DETECT_GITPOD) === false) {
return;
}

const currentUserSetEndpoint = await storage.get(STORAGE_KEY_ADDRESS);
if (!currentUserSetEndpoint || currentUserSetEndpoint === DEFAULT_GITPOD_ENDPOINT) {
const currentHost = window.location.host;
if (currentHost !== new URL(DEFAULT_GITPOD_ENDPOINT).host) {
console.log(`Gitpod extension: switching default endpoint to ${currentHost}.`)
await storage.set(STORAGE_KEY_ADDRESS, parseEndpoint(currentHost));
}
}
}
if (isSiteGitpod()) {
sessionStorage.setItem("browser-extension-installed", "true");
automaticallyUpdateEndpoint();
}
16 changes: 12 additions & 4 deletions src/popup.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { useStorage } from "@plasmohq/storage/hook";
import { useCallback, useEffect, useState } from "react"
import { STORAGE_KEY_ADDRESS, STORAGE_KEY_NEW_TAB } from "~storage";
import { STORAGE_AUTOMATICALLY_DETECT_GITPOD, STORAGE_KEY_ADDRESS, STORAGE_KEY_NEW_TAB } from "~storage";
import { parseEndpoint } from "~utils/parse-endpoint";
import React from "react";

import "./popup.css"
import { InputField } from "~components/forms/InputField";
import { TextInput } from "~components/forms/TextInputField";
import { CheckboxInputField } from "~components/forms/CheckboxInputField";
import { DEFAULT_GITPOD_ENDPOINT } from "~constants";

function IndexPopup() {
const [error, setError] = useState<string>();
Expand All @@ -30,7 +31,8 @@ function IndexPopup() {
setAddress(storedAddress);
}, [storedAddress])

const [openInNewTab, setOpenInNewTab] = useStorage<boolean>(STORAGE_KEY_NEW_TAB, false);
const [openInNewTab, setOpenInNewTab] = useStorage<boolean>(STORAGE_KEY_NEW_TAB, true);
const [automaticallyDetect, setAutomaticallyDetect] = useStorage<boolean>(STORAGE_AUTOMATICALLY_DETECT_GITPOD, true);

return (
<div
Expand All @@ -45,7 +47,7 @@ function IndexPopup() {
<form className="w-full">
<InputField
label="Gitpod URL"
hint="Gitpod instance URL, e.g. https://gitpod.io."
hint={`Gitpod instance URL, e.g. ${DEFAULT_GITPOD_ENDPOINT}.`}
topMargin={false}
>
<div className="flex space-x-2">
Expand All @@ -60,7 +62,13 @@ function IndexPopup() {
<CheckboxInputField
label="Open Workspaces in a new tab"
checked={openInNewTab}
onChange={(checked) => setOpenInNewTab(checked)}
onChange={setOpenInNewTab}
/>
<CheckboxInputField
label="Automatically switch to Gitpod Dedicated"
hint="Upon visiting a Gitpod Dedicated instance, switch to it"
checked={automaticallyDetect}
onChange={setAutomaticallyDetect}
/>
</form>

Expand Down
3 changes: 2 additions & 1 deletion src/storage.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

export const STORAGE_KEY_ADDRESS = "gitpod-installation-address";
export const STORAGE_KEY_NEW_TAB = "gitpod-installation-new-tab";
export const STORAGE_KEY_NEW_TAB = "gitpod-installation-new-tab";
export const STORAGE_AUTOMATICALLY_DETECT_GITPOD = "gitpod-installation-automatically-detect-gitpod";
25 changes: 25 additions & 0 deletions test/src/button-contributions-copy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,31 @@

export type SupportedApplication = "github" | "gitlab" | "bitbucket-server" | "bitbucket";

const resolveMetaAppName = (head: HTMLHeadElement): string | undefined => {
const metaApplication = head.querySelector("meta[name=application-name]");
const ogApplication = head.querySelector("meta[property='og:site_name']");

if (metaApplication) {
return metaApplication.getAttribute("content") || undefined;
} else if (ogApplication) {
return ogApplication.getAttribute("content") || undefined;
}

return undefined;
}

/**
* Provides a fast check to see if the current URL is on a supported site.
*/
export const isSiteSuitable = (): boolean => {
const appName = resolveMetaAppName(document.head);
if (!appName) {
return false;
}
const allowedApps = ["GitHub", "GitLab", "Bitbucket"];
return allowedApps.includes(appName);
}

export interface ButtonContributionParams {
/**
* A unique id for the button contribution. Used to identify the button in the UI.
Expand Down
55 changes: 55 additions & 0 deletions test/src/button-contributions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,61 @@ import { expect } from "chai";
import { describe, it, before, after } from 'mocha';
import { buttonContributions } from "./button-contributions-copy.js";

describe("Query Selector Tests", function () {
let browser: Browser;
let page: Page;

before(async function () {
browser = await puppeteer.launch({
headless: "new",
});
page = await browser.newPage();
});

after(async function () {
await browser.close();
});

async function testHost() {
const all = buttonContributions.flatMap((x) => x.exampleUrls);
for (const url of all) {
it(`should detect the platform for ${url}`, async function () {
await page.goto(url);

const foundMatch = await page.evaluate(() => {
const resolveMetaAppName = (head: HTMLHeadElement): string | undefined => {
const metaApplication = head.querySelector("meta[name=application-name]");
const ogApplication = head.querySelector("meta[property='og:site_name']");

if (metaApplication) {
return metaApplication.getAttribute("content") || undefined;
} else if (ogApplication) {
return ogApplication.getAttribute("content") || undefined;
}

return undefined;
}

const isSiteSuitable = (): boolean => {
const appName = resolveMetaAppName(document.head);
if (!appName) {
return false;
}
const allowedApps = ["GitHub", "GitLab", "Bitbucket"];
return allowedApps.includes(appName);
}

return isSiteSuitable();
});
expect(foundMatch, `Expected to find a match for '${url}'`).to.be.true;
}).timeout(30_000);

}
}

testHost();
});

describe("Query Selector Tests", function () {
let browser: Browser;
let page: Page;
Expand Down

0 comments on commit 925b504

Please sign in to comment.