[Feature] Show icons in releases page. (#98)

* added back scripting permission

* github releases now have icons

* gitea releases now have icons

* gitlab releases now have icons

* gitee releases now have icons

* removed console.log call

* added underscores to all intentional unused function parameters in transformFileName functions

---------

Co-authored-by: Philipp Kief <philipp.kief@gmx.de>
This commit is contained in:
Michael Goodman 2024-07-09 13:03:05 +03:00 committed by GitHub
parent d8b1116af0
commit 12ce1eb996
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 152 additions and 21 deletions

View File

@ -20,3 +20,16 @@ img[data-material-icons-extension='icon'] + svg.octicon-file-directory-open-fill
img[data-material-icons-extension='icon'] + svg.octicon-file-directory-fill { img[data-material-icons-extension='icon'] + svg.octicon-file-directory-fill {
display: none !important; display: none !important;
} }
/* github package icon spacing fix */
.octicon-package[data-material-icons-extension] {
margin-right: 5px;
}
.octicon-file-zip[data-material-icons-extension] {
margin-right: 5px;
}
.releases-download-list .item a {
display: flex;
align-items: center;
}

View File

@ -26,22 +26,28 @@ export function replaceIconInRow(
provider: Provider, provider: Provider,
iconPack: string | null iconPack: string | null
): void { ): void {
const fileName = itemRow let fileName = itemRow
.querySelector(provider.selectors.filename) .querySelector(provider.selectors.filename)
?.textContent// get the last folder for the icon ?.textContent // get the last folder for the icon
?.split('/') ?.split('/')
.reverse()[0] .reverse()[0]
.trim() // when using textContent, it can add multiple types of whitespace,
// remove possible sha from submodule // using regex to replace them with a single space,
// matches 4 or more to future proof in case they decide to increase it. // can be used later to transform the filename
.replace(/\s+@\s+[a-fA-F0-9]{4,}$/, ''); .replace(/\s+/g, ' ')
.trim();
if (!fileName) return; if (!fileName) return;
const iconEl = itemRow.querySelector( const iconEl = itemRow.querySelector(
provider.selectors.icon provider.selectors.icon
) as HTMLElement | null; ) as HTMLElement | null;
if (iconEl?.getAttribute('data-material-icons-extension')) return; if (iconEl?.getAttribute('data-material-icons-extension')) return;
if (iconEl) replaceIcon(iconEl, fileName, itemRow, provider, iconPack);
if (!iconEl) return;
fileName = provider.transformFileName(itemRow, iconEl, fileName);
replaceIcon(iconEl, fileName, itemRow, provider, iconPack);
} }
function replaceIcon( function replaceIcon(

View File

@ -15,4 +15,9 @@ export interface Provider {
getIsSymlink: (params: { row: HTMLElement; icon: HTMLElement }) => boolean; getIsSymlink: (params: { row: HTMLElement; icon: HTMLElement }) => boolean;
getIsLightTheme: () => boolean; getIsLightTheme: () => boolean;
replaceIcon: (oldIcon: HTMLElement, newIcon: HTMLElement) => void; replaceIcon: (oldIcon: HTMLElement, newIcon: HTMLElement) => void;
transformFileName: (
rowEl: HTMLElement,
iconEl: HTMLElement,
fileName: string
) => string;
} }

View File

@ -78,5 +78,12 @@ export default function azure(): Provider {
subtree: true, subtree: true,
}); });
}, },
transformFileName: (
_rowEl: HTMLElement,
_iconEl: HTMLElement,
fileName: string
): string => {
return fileName;
},
}; };
} }

View File

@ -46,5 +46,12 @@ export default function bitbucket(): Provider {
svgEl.parentNode?.replaceChild(newSVG, svgEl); svgEl.parentNode?.replaceChild(newSVG, svgEl);
}, },
onAdd: () => {}, onAdd: () => {},
transformFileName: (
_rowEl: HTMLElement,
_iconEl: HTMLElement,
fileName: string
): string => {
return fileName;
},
}; };
} }

View File

@ -10,9 +10,10 @@ export default function gitea(): Provider {
}, },
], ],
selectors: { selectors: {
row: 'tr.ready.entry', row: 'tr.ready.entry, details.download ul.list li',
filename: 'td.name.four.wide > span.truncate > a', filename:
icon: 'td.name.four.wide > span.truncate > svg', 'td.name.four.wide > span.truncate > a, a[download] strong, a.archive-link strong',
icon: 'td.name.four.wide > span.truncate > svg, .octicon-package, .octicon-file-zip',
// Element by which to detect if the tested domain is gitea. // Element by which to detect if the tested domain is gitea.
detect: 'body > .full.height > .page-content[role=main]', detect: 'body > .full.height > .page-content[role=main]',
}, },
@ -38,5 +39,20 @@ export default function gitea(): Provider {
svgEl.parentNode?.replaceChild(newSVG, svgEl); svgEl.parentNode?.replaceChild(newSVG, svgEl);
}, },
onAdd: () => {}, onAdd: () => {},
transformFileName: (
rowEl: HTMLElement,
_iconEl: HTMLElement,
fileName: string
): string => {
// try to match the 'Source code (zip)' type of rows in releases page in github.
if (
rowEl.querySelector('.archive-link') &&
fileName.includes('Source code')
) {
return fileName.replace(/\s+\((.*?)\)$/, '.$1');
}
return fileName;
},
}; };
} }

View File

@ -11,12 +11,17 @@ export default function gitee(): Provider {
], ],
selectors: { selectors: {
// File list row, README header, file view header // File list row, README header, file view header
row: '#git-project-content .tree-content .row.tree-item, .file_title, .blob-description', row: `#git-project-content .tree-content .row.tree-item,
.file_title,
.blob-description,
.release-body .releases-download-list .item`,
// File name table cell, Submodule name table cell, file view header // File name table cell, Submodule name table cell, file view header
filename: filename: `.tree-list-item > a,
'.tree-list-item > a, .tree-item-submodule-name a, span.file_name', .tree-item-submodule-name a,
span.file_name,
a`,
// The iconfont icon not including the delete button icon in the file view header // The iconfont icon not including the delete button icon in the file view header
icon: 'i.iconfont:not(.icon-delete)', icon: 'i.iconfont:not(.icon-delete), i.icon',
// Element by which to detect if the tested domain is gitee. // Element by which to detect if the tested domain is gitee.
detect: null, detect: null,
}, },
@ -42,5 +47,20 @@ export default function gitee(): Provider {
svgEl.parentNode?.replaceChild(newSVG, svgEl); svgEl.parentNode?.replaceChild(newSVG, svgEl);
}, },
onAdd: () => {}, onAdd: () => {},
transformFileName: (
rowEl: HTMLElement,
_iconEl: HTMLElement,
fileName: string
): string => {
// try to match the 'Source code (zip)' type of rows in releases page in github.
if (
rowEl.classList.contains('item') &&
fileName.includes('Source code')
) {
return fileName.replace(/\s+\((.*?)\)$/, '.$1');
}
return fileName;
},
}; };
} }

View File

@ -14,17 +14,21 @@ export default function github(): Provider {
file-tree .ActionList-content, file-tree .ActionList-content,
a.tree-browser-result, a.tree-browser-result,
.PRIVATE_TreeView-item-content, .PRIVATE_TreeView-item-content,
.react-directory-filename-column`, .react-directory-filename-column,
.Box details .Box-row`,
filename: `div[role="rowheader"] > span, filename: `div[role="rowheader"] > span,
.ActionList-item-label, .ActionList-item-label,
a.tree-browser-result > marked-text, a.tree-browser-result > marked-text,
.PRIVATE_TreeView-item-content > .PRIVATE_TreeView-item-content-text, .PRIVATE_TreeView-item-content > .PRIVATE_TreeView-item-content-text,
.react-directory-filename-column a`, .react-directory-filename-column a,
a.Truncate`,
icon: `.octicon-file, icon: `.octicon-file,
.octicon-file-directory-fill, .octicon-file-directory-fill,
.octicon-file-directory-open-fill, .octicon-file-directory-open-fill,
.octicon-file-submodule, .octicon-file-submodule,
.react-directory-filename-column > svg`, .react-directory-filename-column > svg,
.octicon-package,
.octicon-file-zip`,
// Element by which to detect if the tested domain is github. // Element by which to detect if the tested domain is github.
detect: 'body > div[data-turbo-body]', detect: 'body > div[data-turbo-body]',
}, },
@ -82,5 +86,26 @@ export default function github(): Provider {
} }
}, },
onAdd: () => {}, onAdd: () => {},
transformFileName: (
rowEl: HTMLElement,
_iconEl: HTMLElement,
fileName: string
): string => {
// remove possible sha from submodule
// matches 4 or more to future proof in case they decide to increase it.
if (fileName.includes('@')) {
return fileName.replace(/\s+@\s+[a-fA-F0-9]{4,}$/, '');
}
// try to match the 'Source code (zip)' type of rows in releases page in github.
if (
rowEl.classList.contains('Box-row') &&
fileName.includes('Source code')
) {
return fileName.replace(/\s+\((.*?)\)$/, '.$1');
}
return fileName;
},
}; };
} }

View File

@ -11,12 +11,20 @@ export default function gitlab(): Provider {
], ],
selectors: { selectors: {
// Row in file list, file view header // Row in file list, file view header
row: 'table[data-testid="file-tree-table"].table.tree-table tr.tree-item, table[data-qa-selector="file_tree_table"] tr, .file-header-content', row: `table[data-testid="file-tree-table"].table.tree-table tr.tree-item,
table[data-qa-selector="file_tree_table"] tr,
.file-header-content,
.gl-card[data-testid="release-block"] .js-assets-list ul li`,
// Cell in file list, file view header, readme header // Cell in file list, file view header, readme header
filename: filename: `td.tree-item-file-name .tree-item-link,
'td.tree-item-file-name .tree-item-link, td.tree-item-file-name, .file-header-content .file-title-name, .file-header-content .gl-link', td.tree-item-file-name,
.file-header-content .file-title-name,
.file-header-content .gl-link,
.gl-link`,
// Any icon not contained in a button // Any icon not contained in a button
icon: 'td.tree-item-file-name .tree-item-link svg, .tree-item svg, .file-header-content svg:not(.gl-button-icon)', icon: `td.tree-item-file-name .tree-item-link svg,
.tree-item svg, .file-header-content svg:not(.gl-button-icon),
.gl-link svg.gl-icon[data-testid="doc-code-icon"]`,
// Element by which to detect if the tested domain is gitlab. // Element by which to detect if the tested domain is gitlab.
detect: 'body.page-initialized[data-page]', detect: 'body.page-initialized[data-page]',
}, },
@ -46,5 +54,22 @@ export default function gitlab(): Provider {
svgEl.parentNode?.replaceChild(newSVG, svgEl); svgEl.parentNode?.replaceChild(newSVG, svgEl);
}, },
onAdd: () => {}, onAdd: () => {},
transformFileName: (
rowEl: HTMLElement,
_iconEl: HTMLElement,
fileName: string
): string => {
// try to match the 'Source code (zip)' type of rows in releases page in github.
if (
rowEl.parentElement?.parentElement?.classList.contains(
'js-assets-list'
) &&
fileName.includes('Source code')
) {
return fileName.replace(/\s+\((.*?)\)$/, '.$1');
}
return fileName;
},
}; };
} }

View File

@ -70,5 +70,12 @@ export default function sourceforge(): Provider {
} }
}, },
onAdd: () => {}, onAdd: () => {},
transformFileName: (
_rowEl: HTMLElement,
_iconEl: HTMLElement,
fileName: string
): string => {
return fileName;
},
}; };
} }