From 6bfd4c2e6fe00d7daa5bfe173bdbaac174b62418 Mon Sep 17 00:00:00 2001 From: Tobias Jacksteit Date: Fri, 29 May 2020 23:43:34 +0800 Subject: [PATCH 1/4] configurable host overrides --- src/js/components/Options.js | 35 ++++++++++++++++++-- src/js/content.js | 15 ++++++--- src/js/remoteServices.js | 58 +++++++++++++++++++++++---------- src/js/utils/browser.js | 5 ++- src/js/utils/messageHandlers.js | 7 +++- src/js/utils/settings.js | 17 ++++++++++ src/js/utils/urlMatcher.js | 55 +++++++++++++++++++++++++++---- 7 files changed, 158 insertions(+), 34 deletions(-) create mode 100644 src/js/utils/settings.js diff --git a/src/js/components/Options.js b/src/js/components/Options.js index c54af85..6f95a18 100644 --- a/src/js/components/Options.js +++ b/src/js/components/Options.js @@ -3,18 +3,23 @@ import { observable } from "mobx" import { observer } from "mobx-react" import { isChrome, getSettings, setStorage } from "utils/browser" import ApiClient from "api/Client" +import remoteServices from "../remoteServices"; +import { map } from "lodash" +import { getHostOverridesFromSettings } from "../utils/settings" @observer class Options extends Component { @observable subdomain = "" @observable apiKey = "" + @observable hostOverrides = {} @observable errorMessage = null @observable isSuccess = false componentDidMount() { - getSettings(false).then(({ subdomain, apiKey }) => { - this.subdomain = subdomain || "" - this.apiKey = apiKey || "" + getSettings(false).then((storeData) => { + this.subdomain = storeData.subdomain || "" + this.apiKey = storeData.apiKey || "" + this.hostOverrides = getHostOverridesFromSettings(storeData) || {} }) } @@ -22,13 +27,19 @@ class Options extends Component { this[event.target.name] = event.target.value.trim() } + onChangeHostOverrides = event => { + this.hostOverrides[event.target.name] = event.target.value.trim() + } + handleSubmit = _event => { this.isSuccess = false this.errorMessage = null + setStorage({ subdomain: this.subdomain, apiKey: this.apiKey, settingTimeTrackingHHMM: false, + ...this.hostOverrides, }).then(() => { const { version } = chrome.runtime.getManifest() const apiClient = new ApiClient({ @@ -93,6 +104,24 @@ class Options extends Component { Den API-Schlüssel findest du in deinem Profil unter "Integrationen".

+
+ {map( + remoteServices, + (remoteService, remoteServiceKey) => + remoteService.allowHostOverride && ( +
+ + +
+ ), + )} diff --git a/src/js/content.js b/src/js/content.js index 532c3db..17c8b47 100644 --- a/src/js/content.js +++ b/src/js/content.js @@ -7,11 +7,18 @@ import { createServiceFinder } from "utils/urlMatcher" import remoteServices from "./remoteServices" import { ContentMessenger } from "utils/messaging" import "../css/content.scss" +import { getSettings } from "./utils/browser" +import { getHostOverridesFromSettings } from "./utils/settings" const popupRef = createRef() -const findService = createServiceFinder(remoteServices)(document) -chrome.runtime.onConnect.addListener(function(port) { +let findService +getSettings().then((settings) => { + const hostOverrides = getHostOverridesFromSettings(settings, true) + findService = createServiceFinder(remoteServices, hostOverrides)(document) +}) + +chrome.runtime.onConnect.addListener(function (port) { const messenger = new ContentMessenger(port) function clickHandler(event) { @@ -42,10 +49,10 @@ chrome.runtime.onConnect.addListener(function(port) { leave={{ opacity: "0" }} config={config.stiff} > - {service => + {(service) => service && // eslint-disable-next-line react/display-name - (props => ( + ((props) => ( document => export default { asana: { name: "asana", + host: "https://app.asana.com", urlPatterns: [ - [/^https:\/\/app.asana.com\/0\/([^/]+)\/(\d+)/, ["domainUserId", "id"]], - [/^https:\/\/app.asana.com\/0\/search\/([^/]+)\/(\d+)/, ["domainUserId", "id"]], + [/^__HOST__\/0\/([^/]+)\/(\d+)/, ["domainUserId", "id"]], + [/^__HOST__\/0\/search\/([^/]+)\/(\d+)/, ["domainUserId", "id"]], ], description: document => document.querySelector(".ItemRow--highlighted textarea")?.textContent?.trim() || @@ -19,32 +20,38 @@ export default { document.querySelector(".SingleTaskPane textarea")?.textContent?.trim() || document.querySelector(".SingleTaskTitleInput-taskName textarea")?.textContent?.trim(), projectId: projectIdentifierBySelector(".TopbarPageHeaderStructure-titleRow h1"), + allowHostOverride: false, }, "github-pr": { name: "github", - urlPatterns: ["https\\://github.com/:org/:repo/pull/:id(/:tab)"], + host: "https://github.com", + urlPatterns: ["__HOST__/:org/:repo/pull/:id(/:tab)"], id: (document, service, { org, repo, id }) => [service.key, org, repo, id].join("."), description: document => document.querySelector(".js-issue-title")?.textContent?.trim(), projectId: projectIdentifierBySelector(".js-issue-title"), + allowHostOverride: true, }, "github-issue": { name: "github", - urlPatterns: ["https\\://github.com/:org/:repo/issues/:id"], + host: "https://github.com", + urlPatterns: ["__HOST__/:org/:repo/issues/:id"], id: (document, service, { org, repo, id }) => [service.key, org, repo, id].join("."), description: (document, service, { org, repo, id }) => document.querySelector(".js-issue-title")?.textContent?.trim(), projectId: projectIdentifierBySelector(".js-issue-title"), + allowHostOverride: true, }, jira: { name: "jira", + host: "https://:org.atlassian.net", urlPatterns: [ - "https\\://:org.atlassian.net/secure/RapidBoard.jspa", - "https\\://:org.atlassian.net/browse/:id", - "https\\://:org.atlassian.net/jira/software/projects/:projectId/boards/:board", - "https\\://:org.atlassian.net/jira/software/projects/:projectId/boards/:board/backlog", + "__HOST__/secure/RapidBoard.jspa", + "__HOST__/browse/:id", + "__HOST__/jira/software/projects/:projectId/boards/:board", + "__HOST__/jira/software/projects/:projectId/boards/:board/backlog", ], queryParams: { id: "selectedIssue", @@ -59,11 +66,13 @@ export default { document.querySelector(".ghx-selected .ghx-summary")?.textContent?.trim() return `#${id} ${title || ""}` }, + allowHostOverride: true, }, meistertask: { name: "meistertask", - urlPatterns: ["https\\://www.meistertask.com/app/task/:id/:slug"], + host: "https://www.meistertask.com", + urlPatterns: ["/app/task/:id/:slug"], description: document => { const json = document.getElementById("mt-toggl-data")?.dataset?.togglJson || "{}" const data = JSON.parse(json) @@ -75,30 +84,36 @@ export default { const match = data.taskName?.match(projectRegex) || data.projectName?.match(projectRegex) return match && match[1] }, + allowHostOverride: false, }, trello: { name: "trello", - urlPatterns: ["https\\://trello.com/c/:id/:title"], + host: "https://trello.com", + urlPatterns: ["__HOST__/c/:id/:title"], description: (document, service, { title }) => document.querySelector(".js-title-helper")?.textContent?.trim() || title, projectId: document => projectIdentifierBySelector(".js-title-helper")(document) || projectIdentifierBySelector(".js-board-editing-target")(document), + allowHostOverride: false, }, youtrack: { name: "youtrack", - urlPatterns: ["https\\://:org.myjetbrains.com/youtrack/issue/:id"], + host: "https://:org.myjetbrains.com", + urlPatterns: ["__HOST__/youtrack/issue/:id"], description: document => document.querySelector("yt-issue-body h1")?.textContent?.trim(), projectId: projectIdentifierBySelector("yt-issue-body h1"), + allowHostOverride: true, }, wrike: { name: "wrike", + host: "https://www.wrike.com", urlPatterns: [ - "https\\://www.wrike.com/workspace.htm#path=mywork", - "https\\://www.wrike.com/workspace.htm#path=folder", + "__HOST__/workspace.htm#path=mywork", + "__HOST__/workspace.htm#path=folder", "https\\://app-eu.wrike.com/workspace.htm#path=mywork", "https\\://app-eu.wrike.com/workspace.htm#path=folder", ], @@ -107,39 +122,46 @@ export default { }, description: document => document.querySelector(".title-field-ghost")?.textContent?.trim(), projectId: projectIdentifierBySelector(".header-title__main"), + allowHostOverride: false, }, wunderlist: { name: "wunderlist", - urlPatterns: ["https\\://www.wunderlist.com/(webapp)#/tasks/:id(/*)"], + host: "https://www.wunderlist.com", + urlPatterns: ["__HOST__/(webapp)#/tasks/:id(/*)"], description: document => document .querySelector(".taskItem.selected .taskItem-titleWrapper-title") ?.textContent?.trim(), projectId: projectIdentifierBySelector(".taskItem.selected .taskItem-titleWrapper-title"), + allowHostOverride: false, }, "gitlab-mr": { name: "gitlab", + host: "https://gitlab.com", urlPatterns: [ - "https\\://gitlab.com/:org/:group/:projectId/-/merge_requests/:id", - "https\\://gitlab.com/:org/:projectId/-/merge_requests/:id", + "__HOST__/:org/:group/:projectId/-/merge_requests/:id", + "__HOST__/:org/:projectId/-/merge_requests/:id", ], description: (document, service, { id }) => { const title = document.querySelector("h2.title")?.textContent?.trim() return `#${id} ${title || ""}`.trim() }, + allowHostOverride: true, }, "gitlab-issues": { name: "gitlab", + host: "https://gitlab.com", urlPatterns: [ - "https\\://gitlab.com/:org/:group/:projectId/-/issues/:id", - "https\\://gitlab.com/:org/:projectId/-/issues/:id", + "__HOST__/:org/:group/:projectId/-/issues/:id", + "__HOST__/:org/:projectId/-/issues/:id", ], description: (document, service, { id }) => { const title = document.querySelector("h2.title")?.textContent?.trim() return `#${id} ${title || ""}`.trim() }, + allowHostOverride: true, }, } diff --git a/src/js/utils/browser.js b/src/js/utils/browser.js index 985fbea..c6da9c7 100644 --- a/src/js/utils/browser.js +++ b/src/js/utils/browser.js @@ -1,11 +1,14 @@ import { head } from "lodash/fp" +import remoteServices from "../remoteServices" + export const isChrome = () => typeof browser === "undefined" && chrome export const isFirefox = () => typeof browser !== "undefined" && chrome const DEFAULT_SUBDOMAIN = "unset" export const getSettings = (withDefaultSubdomain = true) => { - const keys = ["subdomain", "apiKey", "settingTimeTrackingHHMM"] + const keys = ["subdomain", "apiKey", "settingTimeTrackingHHMM", + ...Object.keys(remoteServices).map(key => `hostOverrides:${key}`)] const { version } = chrome.runtime.getManifest() if (isChrome()) { return new Promise(resolve => { diff --git a/src/js/utils/messageHandlers.js b/src/js/utils/messageHandlers.js index 705de4b..6f3615c 100644 --- a/src/js/utils/messageHandlers.js +++ b/src/js/utils/messageHandlers.js @@ -11,8 +11,13 @@ import { get, forEach, reject, isNil } from "lodash/fp" import { createMatcher } from "utils/urlMatcher" import remoteServices from "remoteServices" import { queryTabs, isBrowserTab, getSettings, setStorage } from "utils/browser" +import { getHostOverridesFromSettings } from "./settings" -const matcher = createMatcher(remoteServices) +let matcher +getSettings().then((settings) => { + const hostOverrides = getHostOverridesFromSettings(settings, true) + matcher = createMatcher(remoteServices, hostOverrides) +}) export function tabUpdated(tab, { messenger, settings }) { messenger.connectTab(tab) diff --git a/src/js/utils/settings.js b/src/js/utils/settings.js new file mode 100644 index 0000000..5cbc464 --- /dev/null +++ b/src/js/utils/settings.js @@ -0,0 +1,17 @@ +import { filter, fromPairs, map, toPairs } from "lodash" + +export const getHostOverridesFromSettings = (settings, removePrefix) => { + return fromPairs( + map( + filter(toPairs(settings), (item) => { + return item[0].indexOf("hostOverrides") !== -1 + }), + (item) => { + if (removePrefix) { + item[0] = item[0].replace("hostOverrides:", "") + } + return item + }, + ), + ) +} diff --git a/src/js/utils/urlMatcher.js b/src/js/utils/urlMatcher.js index 4767fa2..47aa6c6 100644 --- a/src/js/utils/urlMatcher.js +++ b/src/js/utils/urlMatcher.js @@ -1,5 +1,5 @@ import UrlPattern from "url-pattern" -import { isFunction, isUndefined, compose, toPairs, map, pipe, isNil } from "lodash/fp" +import { isFunction, isUndefined, compose, toPairs, map, pipe, isNil, convert } from "lodash/fp" import { asArray } from "./index" import queryString from "query-string" @@ -39,15 +39,36 @@ const createEvaluator = args => fnOrValue => { return fnOrValue } +const prepareHostForRegExp = (host) => { + if (isUndefined(host)) { + return + } + + return host.replace(":", "\\:")//.replace(/\//g, "\\/") +} + +const replaceHostInPattern = (host, pattern) => { + if(typeof pattern === "string") { + return pattern.replace("__HOST__", prepareHostForRegExp(host)) + } else if(pattern instanceof RegExp) { + return new RegExp(pattern.source.replace("__HOST__", prepareHostForRegExp(host))) + } else { + console.error("Invalid type for pattern %v, no host replacement performed", pattern) + return pattern + } +} + const parseServices = compose( map(([key, config]) => ({ ...config, key, patterns: config.urlPatterns.map(pattern => { if (Array.isArray(pattern)) { - return new UrlPattern(...pattern) + return new UrlPattern( + ...pattern.map((p, index) => (index === 0 ? replaceHostInPattern(config.host, p) : p)), + ) } - return new UrlPattern(pattern) + return new UrlPattern(replaceHostInPattern(config.host, pattern)) }), })), toPairs, @@ -72,8 +93,28 @@ export const createEnhancer = document => service => { } } -export const createMatcher = remoteServices => { - const services = parseServices(remoteServices) +const applyHostOverrides = (remoteServices, hostOverrides) => { + let appliedRemoteServices = Object.assign(remoteServices) + if (isUndefined(hostOverrides)) { + console.error("No overrides found.") + return remoteServices + } + + Object.keys(remoteServices).forEach((key) => { + const remoteService = remoteServices[key]; + appliedRemoteServices[key] = { + ...remoteService, + key, + host: (hostOverrides && hostOverrides[key]) || remoteService.host, + } + }) + + return appliedRemoteServices +} + +export const createMatcher = (remoteServices, hostOverrides) => { + const services = parseServices(applyHostOverrides(remoteServices, hostOverrides)) + return tabUrl => { const { origin, pathname, hash, query } = parseUrl(tabUrl) const url = `${origin}${pathname}${hash}` @@ -99,8 +140,8 @@ export const createMatcher = remoteServices => { } } -export const createServiceFinder = remoteServices => document => { - const matcher = createMatcher(remoteServices) +export const createServiceFinder = (remoteServices, hostOverrides) => document => { + const matcher = createMatcher(remoteServices, hostOverrides) const enhancer = createEnhancer(document) return pipe( matcher, From 45cd9dbbe97a22d456a75980fd365c75092ad287 Mon Sep 17 00:00:00 2001 From: Tobias Jacksteit Date: Wed, 3 Jun 2020 14:47:35 +0800 Subject: [PATCH 2/4] base host overrides on name of service instead of key and hide the options by default --- src/css/options.scss | 11 +++++ src/js/components/Options.js | 77 +++++++++++++++++++++++---------- src/js/utils/browser.js | 2 +- src/js/utils/messageHandlers.js | 9 +++- src/js/utils/urlMatcher.js | 4 +- 5 files changed, 75 insertions(+), 28 deletions(-) diff --git a/src/css/options.scss b/src/css/options.scss index 8b42215..d5eccfa 100644 --- a/src/css/options.scss +++ b/src/css/options.scss @@ -38,5 +38,16 @@ .text-danger { color: $red; } + + .moco-bx-override-hosts { + &-container { + padding: 0 20px; + text-align: center; + } + &-btn { + cursor: pointer; + text-decoration: underline; + } + } } } diff --git a/src/js/components/Options.js b/src/js/components/Options.js index 6f95a18..7f35194 100644 --- a/src/js/components/Options.js +++ b/src/js/components/Options.js @@ -3,8 +3,8 @@ import { observable } from "mobx" import { observer } from "mobx-react" import { isChrome, getSettings, setStorage } from "utils/browser" import ApiClient from "api/Client" -import remoteServices from "../remoteServices"; -import { map } from "lodash" +import remoteServices from "../remoteServices" +import { map, sortedUniqBy, filter } from "lodash" import { getHostOverridesFromSettings } from "../utils/settings" @observer @@ -14,8 +14,25 @@ class Options extends Component { @observable hostOverrides = {} @observable errorMessage = null @observable isSuccess = false + @observable servicesHostOverrideList = [] + @observable showHostOverrideOptions = false componentDidMount() { + this.servicesHostOverrideList = sortedUniqBy( + map( + filter(remoteServices, (remoteService) => { + return remoteService.allowHostOverride + }), + (remoteService) => { + return { + name: remoteService.name, + host: remoteService.host, + } + }, + ), + "name", + ) + getSettings(false).then((storeData) => { this.subdomain = storeData.subdomain || "" this.apiKey = storeData.apiKey || "" @@ -23,15 +40,20 @@ class Options extends Component { }) } - onChange = event => { + onChange = (event) => { this[event.target.name] = event.target.value.trim() } - onChangeHostOverrides = event => { - this.hostOverrides[event.target.name] = event.target.value.trim() + onChangeHostOverrides = (event) => { + // ensure to remove path (and trailing slash) from URL, as this can cause problems otherwise + this.hostOverrides[event.target.name] = this.removePathFromUrl(event.target.value.trim()) } - handleSubmit = _event => { + toggleHostOverrideOptions = (event) => { + this.showHostOverrideOptions = !this.showHostOverrideOptions + } + + handleSubmit = (_event) => { this.isSuccess = false this.errorMessage = null @@ -56,13 +78,17 @@ class Options extends Component { this.isSuccess = true this.closeWindow() }) - .catch(error => { + .catch((error) => { this.errorMessage = error.response?.data?.message || "Anmeldung fehlgeschlagen" }) }) } - handleInputKeyDown = event => { + removePathFromUrl = (url) => { + return url.replace(/(\.[a-z]+)\/.*$/, "$1") + } + + handleInputKeyDown = (event) => { if (event.key === "Enter") { this.handleSubmit() } @@ -105,23 +131,26 @@ class Options extends Component {


- {map( - remoteServices, - (remoteService, remoteServiceKey) => - remoteService.allowHostOverride && ( -
- - -
- ), + {!this.showHostOverrideOptions && ( +
+ Zeige Optionen zum Überschreiben
der Service Hosts
+
)} + {this.showHostOverrideOptions && + this.servicesHostOverrideList.map((remoteService) => ( +
+ + +
+ ))} +
diff --git a/src/js/utils/browser.js b/src/js/utils/browser.js index c6da9c7..38d19b5 100644 --- a/src/js/utils/browser.js +++ b/src/js/utils/browser.js @@ -8,7 +8,7 @@ const DEFAULT_SUBDOMAIN = "unset" export const getSettings = (withDefaultSubdomain = true) => { const keys = ["subdomain", "apiKey", "settingTimeTrackingHHMM", - ...Object.keys(remoteServices).map(key => `hostOverrides:${key}`)] + ...Object.values(remoteServices).map(remoteService => `hostOverrides:${remoteService.name}`)] const { version } = chrome.runtime.getManifest() if (isChrome()) { return new Promise(resolve => { diff --git a/src/js/utils/messageHandlers.js b/src/js/utils/messageHandlers.js index 6f3615c..058c4b5 100644 --- a/src/js/utils/messageHandlers.js +++ b/src/js/utils/messageHandlers.js @@ -14,9 +14,14 @@ import { queryTabs, isBrowserTab, getSettings, setStorage } from "utils/browser" import { getHostOverridesFromSettings } from "./settings" let matcher -getSettings().then((settings) => { + +const initMatcher = (settings) => { const hostOverrides = getHostOverridesFromSettings(settings, true) matcher = createMatcher(remoteServices, hostOverrides) +} + +getSettings().then((settings) => { + initMatcher(settings) }) export function tabUpdated(tab, { messenger, settings }) { @@ -59,6 +64,8 @@ export function tabUpdated(tab, { messenger, settings }) { } export function settingsChanged(settings, { messenger }) { + initMatcher(settings) + queryTabs({ currentWindow: true }) .then(reject(isBrowserTab)) .then( diff --git a/src/js/utils/urlMatcher.js b/src/js/utils/urlMatcher.js index 47aa6c6..a6879dc 100644 --- a/src/js/utils/urlMatcher.js +++ b/src/js/utils/urlMatcher.js @@ -101,11 +101,11 @@ const applyHostOverrides = (remoteServices, hostOverrides) => { } Object.keys(remoteServices).forEach((key) => { - const remoteService = remoteServices[key]; + const remoteService = remoteServices[key] appliedRemoteServices[key] = { ...remoteService, key, - host: (hostOverrides && hostOverrides[key]) || remoteService.host, + host: (hostOverrides && hostOverrides[remoteService.name]) || remoteService.host, } }) From 5900cb997aad0b7833510b2b20a8595d22cf0423 Mon Sep 17 00:00:00 2001 From: Tobias Jacksteit Date: Wed, 3 Jun 2020 15:01:38 +0800 Subject: [PATCH 3/4] added unit tests --- test/utils/urlMatcher.test.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/test/utils/urlMatcher.test.js b/test/utils/urlMatcher.test.js index 5b84686..42ae1dd 100644 --- a/test/utils/urlMatcher.test.js +++ b/test/utils/urlMatcher.test.js @@ -6,7 +6,7 @@ describe("utils", () => { let matcher beforeEach(() => { - matcher = createMatcher(remoteServices) + matcher = createMatcher(remoteServices, {}) }) describe("createMatcher", () => { @@ -162,4 +162,27 @@ describe("utils", () => { }) }) }) + + describe("urlMatcher with overrideHosts", () => { + let matcher + + beforeEach(() => { + matcher = createMatcher(remoteServices, { + github: "https://my-custom-github-url.com", + }) + }) + + describe("createMatcher", () => { + it("matches overridden host and path", () => { + const service = matcher("https://my-custom-github-url.com/hundertzehn/mocoapp/pull/123") + expect(service.key).toEqual("github-pr") + expect(service.name).toEqual("github") + }) + + it("doesn't match default host and path", () => { + const service = matcher("https://github.com/hundertzehn/mocoapp/pull/123") + expect(service).toBe(undefined) + }) + }) + }) }) From d02b2b2efb13b8daea0128e9c14e1472d3c87eb2 Mon Sep 17 00:00:00 2001 From: Tobias Jacksteit Date: Mon, 8 Jun 2020 22:01:26 +0800 Subject: [PATCH 4/4] review changes --- src/js/components/Options.js | 35 +++++++++++++-------------------- src/js/content.js | 4 +--- src/js/utils/browser.js | 4 +--- src/js/utils/messageHandlers.js | 4 +--- src/js/utils/settings.js | 17 ---------------- src/js/utils/urlMatcher.js | 2 +- 6 files changed, 18 insertions(+), 48 deletions(-) delete mode 100644 src/js/utils/settings.js diff --git a/src/js/components/Options.js b/src/js/components/Options.js index 7f35194..91804da 100644 --- a/src/js/components/Options.js +++ b/src/js/components/Options.js @@ -4,8 +4,7 @@ import { observer } from "mobx-react" import { isChrome, getSettings, setStorage } from "utils/browser" import ApiClient from "api/Client" import remoteServices from "../remoteServices" -import { map, sortedUniqBy, filter } from "lodash" -import { getHostOverridesFromSettings } from "../utils/settings" +import { pipe, prop, map, sortedUniqBy, filter } from "lodash/fp" @observer class Options extends Component { @@ -18,25 +17,19 @@ class Options extends Component { @observable showHostOverrideOptions = false componentDidMount() { - this.servicesHostOverrideList = sortedUniqBy( - map( - filter(remoteServices, (remoteService) => { - return remoteService.allowHostOverride - }), - (remoteService) => { - return { - name: remoteService.name, - host: remoteService.host, - } - }, - ), - "name", - ) + this.servicesHostOverrideList = pipe( + filter(prop("allowHostOverride")), + map((remoteService) => ({ + name: remoteService.name, + host: remoteService.host, + })), + sortedUniqBy("name"), + )(remoteServices) getSettings(false).then((storeData) => { this.subdomain = storeData.subdomain || "" this.apiKey = storeData.apiKey || "" - this.hostOverrides = getHostOverridesFromSettings(storeData) || {} + this.hostOverrides = storeData.hostOverrides || {} }) } @@ -49,7 +42,7 @@ class Options extends Component { this.hostOverrides[event.target.name] = this.removePathFromUrl(event.target.value.trim()) } - toggleHostOverrideOptions = (event) => { + toggleHostOverrideOptions = () => { this.showHostOverrideOptions = !this.showHostOverrideOptions } @@ -61,7 +54,7 @@ class Options extends Component { subdomain: this.subdomain, apiKey: this.apiKey, settingTimeTrackingHHMM: false, - ...this.hostOverrides, + hostOverrides: this.hostOverrides, }).then(() => { const { version } = chrome.runtime.getManifest() const apiClient = new ApiClient({ @@ -142,8 +135,8 @@ class Options extends Component { { - const hostOverrides = getHostOverridesFromSettings(settings, true) - findService = createServiceFinder(remoteServices, hostOverrides)(document) + findService = createServiceFinder(remoteServices, settings.hostOverrides)(document) }) chrome.runtime.onConnect.addListener(function (port) { diff --git a/src/js/utils/browser.js b/src/js/utils/browser.js index 38d19b5..92d81cf 100644 --- a/src/js/utils/browser.js +++ b/src/js/utils/browser.js @@ -1,5 +1,4 @@ import { head } from "lodash/fp" -import remoteServices from "../remoteServices" export const isChrome = () => typeof browser === "undefined" && chrome export const isFirefox = () => typeof browser !== "undefined" && chrome @@ -7,8 +6,7 @@ export const isFirefox = () => typeof browser !== "undefined" && chrome const DEFAULT_SUBDOMAIN = "unset" export const getSettings = (withDefaultSubdomain = true) => { - const keys = ["subdomain", "apiKey", "settingTimeTrackingHHMM", - ...Object.values(remoteServices).map(remoteService => `hostOverrides:${remoteService.name}`)] + const keys = ["subdomain", "apiKey", "settingTimeTrackingHHMM", "hostOverrides"] const { version } = chrome.runtime.getManifest() if (isChrome()) { return new Promise(resolve => { diff --git a/src/js/utils/messageHandlers.js b/src/js/utils/messageHandlers.js index 058c4b5..d006a83 100644 --- a/src/js/utils/messageHandlers.js +++ b/src/js/utils/messageHandlers.js @@ -11,13 +11,11 @@ import { get, forEach, reject, isNil } from "lodash/fp" import { createMatcher } from "utils/urlMatcher" import remoteServices from "remoteServices" import { queryTabs, isBrowserTab, getSettings, setStorage } from "utils/browser" -import { getHostOverridesFromSettings } from "./settings" let matcher const initMatcher = (settings) => { - const hostOverrides = getHostOverridesFromSettings(settings, true) - matcher = createMatcher(remoteServices, hostOverrides) + matcher = createMatcher(remoteServices, settings.hostOverrides) } getSettings().then((settings) => { diff --git a/src/js/utils/settings.js b/src/js/utils/settings.js deleted file mode 100644 index 5cbc464..0000000 --- a/src/js/utils/settings.js +++ /dev/null @@ -1,17 +0,0 @@ -import { filter, fromPairs, map, toPairs } from "lodash" - -export const getHostOverridesFromSettings = (settings, removePrefix) => { - return fromPairs( - map( - filter(toPairs(settings), (item) => { - return item[0].indexOf("hostOverrides") !== -1 - }), - (item) => { - if (removePrefix) { - item[0] = item[0].replace("hostOverrides:", "") - } - return item - }, - ), - ) -} diff --git a/src/js/utils/urlMatcher.js b/src/js/utils/urlMatcher.js index a6879dc..f4fb98a 100644 --- a/src/js/utils/urlMatcher.js +++ b/src/js/utils/urlMatcher.js @@ -44,7 +44,7 @@ const prepareHostForRegExp = (host) => { return } - return host.replace(":", "\\:")//.replace(/\//g, "\\/") + return host.replace(":", "\\:") } const replaceHostInPattern = (host, pattern) => {