diff --git a/src/constants.ts b/src/constants.ts index 162b5a0..6eed942 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,22 +1,70 @@ +const GITHUB_SELECTORS = { + row: [ + '.js-navigation-container[role=grid] > .js-navigation-item', + 'file-tree .ActionList-content', + 'a.tree-browser-result', + '.PRIVATE_TreeView-item-content', + '.react-directory-filename-column', + '[aria-label="Parent directory"]', + ], + filename: [ + 'div[role="rowheader"] > span', + '.ActionList-item-label', + 'a.tree-browser-result > marked-text', + '.PRIVATE_TreeView-item-content > .PRIVATE_TreeView-item-content-text', + '.react-directory-filename-column .react-directory-filename-cell a', + '[aria-label="Parent directory"] div', + ], + icon: [ + '.octicon-file', + '.octicon-file-directory-fill', + '.octicon-file-directory-open-fill', + '.octicon-file-submodule', + '.react-directory-filename-column > svg', + '[aria-label="Parent directory"] svg', + ], +}; + +const GITLAB_SELECTORS = { + row: [ + '.tree-table .tree-item', + '.file-header-content', + '.diff-tree-list .file-row', + ], + filename: [ + '.tree-item-file-name .tree-item-link span:last-of-type', + '.file-title-name', + 'span.gl-truncate-component', + ], + icon: [ + '.folder-icon', + '.file-icon', + 'span svg:has(use[href^="/assets/file_icons/"])', + ], +}; + +const FORGEJO_SELECTORS = { + row: [ + '#repo-files-table .entry', + '#diff-file-tree .item-file', + '#diff-file-tree .item-directory', + ], + filename: ['.name a.muted', 'span.gt-ellipsis'], + icon: ['.octicon-file-directory-fill', '.octicon-file'], +}; + +function mergeSelectors(key: keyof typeof GITHUB_SELECTORS): string { + return [ + ...GITHUB_SELECTORS[key], + ...GITLAB_SELECTORS[key], + ...FORGEJO_SELECTORS[key], + ].join(','); +} + export const SELECTORS = { - row: `.js-navigation-container[role=grid] > .js-navigation-item, - file-tree .ActionList-content, - a.tree-browser-result, - .PRIVATE_TreeView-item-content, - .react-directory-filename-column, - [aria-label="Parent directory"]`, - filename: `div[role="rowheader"] > span, - .ActionList-item-label, - a.tree-browser-result > marked-text, - .PRIVATE_TreeView-item-content > .PRIVATE_TreeView-item-content-text, - .react-directory-filename-column .react-directory-filename-cell a, - [aria-label="Parent directory"] div`, - icon: `.octicon-file, - .octicon-file-directory-fill, - .octicon-file-directory-open-fill, - .octicon-file-submodule, - .react-directory-filename-column > svg, - [aria-label="Parent directory"] svg`, + row: mergeSelectors('row'), + filename: mergeSelectors('filename'), + icon: mergeSelectors('icon'), }; export const icons = { diff --git a/src/entries/content/index.ts b/src/entries/content/index.ts index 57e63bb..216e651 100644 --- a/src/entries/content/index.ts +++ b/src/entries/content/index.ts @@ -7,7 +7,7 @@ import { flavor } from '@/storage'; import { replaceIconInRow, injectStyles } from './lib'; export default defineContentScript({ - matches: ['*://github.com/*'], + matches: ['*://github.com/*', '*://gitlab.com/*', '*://codeberg.org/*'], runAt: 'document_start', main() { // Replacing all icons synchronously prevents visual "blinks" but can diff --git a/src/entries/content/lib.ts b/src/entries/content/lib.ts index fa21443..2d31f8d 100644 --- a/src/entries/content/lib.ts +++ b/src/entries/content/lib.ts @@ -70,12 +70,18 @@ export async function replaceIconInRow(row: HTMLElement) { export async function replaceIcon(icon: HTMLElement, row: HTMLElement) { const fileNameEl = row.querySelector(SELECTORS.filename) as HTMLElement; if (!fileNameEl) return; - const fileName = fileNameEl.textContent?.split('/').at(0).trim(); + const fileName = fileNameEl.textContent + ?.split('/') + .at(0) + .trim() + /* Remove [Unicode LEFT-TO-RIGHT MARK](https://en.wikipedia.org/wiki/Left-to-right_mark) used on GitLab's merge request diff file tree. */ + .replace(/\u200E/g, ''); const isDir = icon.getAttribute('aria-label') === 'Directory' || icon.getAttribute('class')?.includes('octicon-file-directory-') || - icon.classList.contains('icon-directory'); + icon.classList.contains('icon-directory') || + icon.classList.contains('folder-icon'); const isSubmodule = icon.classList.contains('octicon-file-submodule') || fileNameEl diff --git a/web-ext.config.ts b/web-ext.config.ts index c8f0f99..07e7931 100644 --- a/web-ext.config.ts +++ b/web-ext.config.ts @@ -1,5 +1,9 @@ import { defineRunnerConfig } from 'wxt'; export default defineRunnerConfig({ - startUrls: ['https://github.com/catppuccin/catppuccin'], + startUrls: [ + 'https://github.com/catppuccin/catppuccin', + 'https://gitlab.com/gitlab-org/gitlab', + 'https://codeberg.org/forgejo/forgejo', + ], });