diff --git a/.editorconfig b/.editorconfig index 3bdd42c..aa2d804 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,4 +8,8 @@ charset = utf-8 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true -indent_style = tab +indent_style = space +indent_size = 2 + +[*.{txt,md}] +trim_trailing_whitespace = false diff --git a/.eslintrc.json b/.eslintrc.json index 9a123ed..92e5ac1 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,11 +1,11 @@ { - "extends": ["airbnb", "prettier"], - "plugins": ["prettier"], - "rules": { - "prettier/prettier": ["error"] - }, - "globals": { - "window": true, - "document": true - } + "extends": ["airbnb", "prettier"], + "plugins": ["prettier"], + "rules": { + "prettier/prettier": ["error"] + }, + "globals": { + "window": true, + "document": true + } } diff --git a/.prettierrc.json b/.prettierrc.json index 79d13cd..5ac85e2 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,4 +1,4 @@ { - "printWidth": 100, - "singleQuote": true + "printWidth": 100, + "singleQuote": true } diff --git a/LICENSE b/LICENSE index 7621dcd..b75fadf 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ MIT License -Copyright (c) 2020 Claudio Santos, Shiva Poudel and Richard Lam -(MIT) Copyright (c) 2020 Philipp Kief (VSCode Material Icon Theme) +Copyright (c) 2021 Claudio Santos, Shiva Poudel and Richard Lam +(MIT) Copyright (c) 2021 Philipp Kief (VSCode Material Icon Theme) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/package.json b/package.json index 0e6da41..fe031bb 100644 --- a/package.json +++ b/package.json @@ -1,52 +1,52 @@ { - "name": "github-material-icons-extension", - "version": "1.3.0", - "description": "Browser Extension that enhances the GitHub file browser with material icons.", - "main": "src/main.js", - "author": "Claudio Santos", - "license": "MIT", - "homepage": "https://github.com/Claudiohbsantos/github-material-icons-extension#readme", - "repository": { - "type": "git", - "url": "git+https://github.com/Claudiohbsantos/github-material-icons-extension.git" - }, - "bugs": { - "url": "https://github.com/Claudiohbsantos/github-material-icons-extension/issues" - }, - "engines": { - "node": ">=10.0.0", - "npm": ">=6.9.0 <7" - }, - "dependencies": { - "selector-observer": "2.1.6" - }, - "devDependencies": { - "eslint": "7.29.0", - "eslint-config": "0.3.0", - "eslint-config-airbnb": "18.2.1", - "eslint-config-prettier": "8.3.0", - "eslint-plugin-prettier": "3.4.0", - "fs-extra": "10.0.0", - "mkdirp": "1.0.4", - "node-html-parser": "3.3.5", - "npm-run-all": "4.1.5", - "parcel-bundler": "1.12.5", - "prettier": "2.3.1", - "rimraf": "3.0.2", - "sharp": "0.28.3", - "simple-git": "2.40.0", - "svgo": "2.3.0", - "web-ext": "6.1.0" - }, - "scripts": { - "build": "npx rimraf ./dist && npx run-s build-dependencies build-src bundle", - "build-dependencies": "node ./scripts/build-dependencies.js", - "build-src": "node ./scripts/build-src.js", - "rebuild-logos": "node ./scripts/build-extensionIcons.js", - "bundle": "run-p bundle-edge bundle-chrome bundle-firefox", - "bundle-edge": "zip -r material-icons-github-edge-extension.zip dist", - "bundle-chrome": "zip -r material-icons-github-chrome-extension.zip dist", - "bundle-firefox": "web-ext -s ./dist/ -n material-icons-github-firefox-extension.zip -a . build", - "parcel": "parcel build ./src/main.js" - } + "name": "github-material-icons-extension", + "version": "1.3.0", + "description": "Browser Extension that enhances the GitHub file browser with material icons.", + "main": "src/main.js", + "author": "Claudio Santos", + "license": "MIT", + "homepage": "https://github.com/Claudiohbsantos/github-material-icons-extension#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/Claudiohbsantos/github-material-icons-extension.git" + }, + "bugs": { + "url": "https://github.com/Claudiohbsantos/github-material-icons-extension/issues" + }, + "engines": { + "node": ">=10.0.0", + "npm": ">=6.9.0 <7" + }, + "dependencies": { + "selector-observer": "2.1.6" + }, + "devDependencies": { + "eslint": "7.29.0", + "eslint-config": "0.3.0", + "eslint-config-airbnb": "18.2.1", + "eslint-config-prettier": "8.3.0", + "eslint-plugin-prettier": "3.4.0", + "fs-extra": "10.0.0", + "mkdirp": "1.0.4", + "node-html-parser": "3.3.5", + "npm-run-all": "4.1.5", + "parcel-bundler": "1.12.5", + "prettier": "2.3.1", + "rimraf": "3.0.2", + "sharp": "0.28.3", + "simple-git": "2.40.0", + "svgo": "2.3.0", + "web-ext": "6.1.0" + }, + "scripts": { + "build": "npx rimraf ./dist && npx run-s build-dependencies build-src bundle", + "build-dependencies": "node ./scripts/build-dependencies.js", + "build-src": "node ./scripts/build-src.js", + "rebuild-logos": "node ./scripts/build-extensionIcons.js", + "bundle": "run-p bundle-edge bundle-chrome bundle-firefox", + "bundle-edge": "zip -r material-icons-github-edge-extension.zip dist", + "bundle-chrome": "zip -r material-icons-github-chrome-extension.zip dist", + "bundle-firefox": "web-ext -s ./dist/ -n material-icons-github-firefox-extension.zip -a . build", + "parcel": "parcel build ./src/main.js" + } } diff --git a/scripts/build-dependencies.js b/scripts/build-dependencies.js index ca72999..179bd66 100644 --- a/scripts/build-dependencies.js +++ b/scripts/build-dependencies.js @@ -15,29 +15,29 @@ const srcPath = path.resolve(__dirname, '..', 'src'); const vsExtPath = path.resolve(__dirname, '..', 'temp'); const destSVGPath = path.resolve(__dirname, '..', 'optimizedSVGs'); const vsExtExecOptions = { - cwd: vsExtPath, - stdio: 'inherit', + cwd: vsExtPath, + stdio: 'inherit', }; const distIconsExecOptions = { - cwd: path.resolve(destSVGPath), - stdio: 'inherit', + cwd: path.resolve(destSVGPath), + stdio: 'inherit', }; // Copy dependencies from vs code extension. rimraf.sync(vsExtPath); rimraf.sync(destSVGPath); mkdirp(destSVGPath) - .then(() => - git.clone(`https://github.com/PKief/vscode-material-icon-theme.git`, 'temp', ['--depth', '1']) - ) - .then(() => child_process.execSync(`npm install`, vsExtExecOptions)) - .then(() => fs.copy(path.resolve(vsExtPath, 'icons'), path.resolve(destSVGPath))) - .then(() => child_process.exec(`npx svgo --disable=removeViewBox .`, distIconsExecOptions)) - .then(() => child_process.execSync(`npm run build`, vsExtExecOptions)) - .then(() => - fs.copy( - path.resolve(vsExtPath, 'dist', 'material-icons.json'), - path.resolve(srcPath, 'iconMap.json') - ) - ) - .then(() => rimraf.sync(vsExtPath)); + .then(() => + git.clone(`https://github.com/PKief/vscode-material-icon-theme.git`, 'temp', ['--depth', '1']) + ) + .then(() => child_process.execSync(`npm install`, vsExtExecOptions)) + .then(() => fs.copy(path.resolve(vsExtPath, 'icons'), path.resolve(destSVGPath))) + .then(() => child_process.exec(`npx svgo --disable=removeViewBox .`, distIconsExecOptions)) + .then(() => child_process.execSync(`npm run build`, vsExtExecOptions)) + .then(() => + fs.copy( + path.resolve(vsExtPath, 'dist', 'material-icons.json'), + path.resolve(srcPath, 'iconMap.json') + ) + ) + .then(() => rimraf.sync(vsExtPath)); diff --git a/scripts/build-extensionIcons.js b/scripts/build-extensionIcons.js index 378c4b3..d10d794 100644 --- a/scripts/build-extensionIcons.js +++ b/scripts/build-extensionIcons.js @@ -21,13 +21,13 @@ mkdirp(iconsPath).then(generateIcons); * @since 1.4.0 */ function generateIcons() { - targetSizes.map((size) => { - sharp(svgPath) - .png() - .resize({ width: size, height: size }) - .toFile(`${iconsPath}/icon${size}.png`) - .catch(function (err) { - console.log(err); - }); - }); + targetSizes.map((size) => { + sharp(svgPath) + .png() + .resize({ width: size, height: size }) + .toFile(`${iconsPath}/icon${size}.png`) + .catch(function (err) { + console.log(err); + }); + }); } diff --git a/scripts/build-src.js b/scripts/build-src.js index 98b8d19..fd1dec1 100644 --- a/scripts/build-src.js +++ b/scripts/build-src.js @@ -25,26 +25,26 @@ mkdirp(distPath).then(createIconsCache).then(copySrc); * @returns a newly generated promise object. */ function copySrc() { - // Copy manifest file. - const copyManifest = fs.copy( - path.resolve(srcPath, 'manifest.json'), - path.resolve(distPath, 'manifest.json') - ); + // Copy manifest file. + const copyManifest = fs.copy( + path.resolve(srcPath, 'manifest.json'), + path.resolve(distPath, 'manifest.json') + ); - // Copy extension icon. - const copyExtensionLogos = fs.copy( - path.resolve(srcPath, "extensionIcons"), - path.resolve(distPath, "icons") - ); + // Copy extension icon. + const copyExtensionLogos = fs.copy( + path.resolve(srcPath, 'extensionIcons'), + path.resolve(distPath, 'icons') + ); - // Bundle the main script. - const entryFile = path.resolve(srcPath, 'main.js'); - const bundleMainScript = new Parcel(entryFile, { - watch: false, - minify: true, - }).bundle(); + // Bundle the main script. + const entryFile = path.resolve(srcPath, 'main.js'); + const bundleMainScript = new Parcel(entryFile, { + watch: false, + minify: true, + }).bundle(); - return Promise.all([copyManifest, copyExtensionLogos, bundleMainScript]); + return Promise.all([copyManifest, copyExtensionLogos, bundleMainScript]); } /** @@ -53,10 +53,10 @@ function copySrc() { * @since 1.4.0 */ function createIconsCache() { - return new Promise((resolve, reject) => { - fs.copy(path.resolve(srcPath, 'customIcons'), destSVGPath) - .then(() => extractSVGs()) - .then(resolve) - .catch(reject); - }); + return new Promise((resolve, reject) => { + fs.copy(path.resolve(srcPath, 'customIcons'), destSVGPath) + .then(() => extractSVGs()) + .then(resolve) + .catch(reject); + }); } diff --git a/scripts/extract-svgHtml.js b/scripts/extract-svgHtml.js index 71fa67b..aaac2bc 100644 --- a/scripts/extract-svgHtml.js +++ b/scripts/extract-svgHtml.js @@ -13,30 +13,30 @@ const { parse } = require('node-html-parser'); * @returns a newly generated promise object. */ module.exports = function extractSVGs() { - const iconsPath = path.resolve(__dirname, '..', 'optimizedSVGs'); - const destCachePath = path.resolve(__dirname, '..', 'src', 'iconsCache.js'); + const iconsPath = path.resolve(__dirname, '..', 'optimizedSVGs'); + const destCachePath = path.resolve(__dirname, '..', 'src', 'iconsCache.js'); - return new Promise((resolve, reject) => { - fs.readdir(iconsPath) - .then((iconsNames) => - Promise.all( - iconsNames.map((name) => fs.readFile(path.resolve(iconsPath, name), { encoding: 'utf8' })) - ).then((svgStrs) => svgStrs.map((svgStr, i) => [iconsNames[i], parse(svgStr)])) - ) - .then((svgElsEntries) => - svgElsEntries.map((entry) => [ - entry[0], - { - innerHtml: entry[1].firstChild.innerHTML, - viewBox: entry[1].firstChild.getAttribute('viewBox'), - }, - ]) - ) - .then((cacheEntries) => Object.fromEntries(cacheEntries)) - .then((svgsObj) => fs.writeFile(destCachePath, formatCache(svgsObj))) - .then(resolve) - .catch(reject); - }); + return new Promise((resolve, reject) => { + fs.readdir(iconsPath) + .then((iconsNames) => + Promise.all( + iconsNames.map((name) => fs.readFile(path.resolve(iconsPath, name), { encoding: 'utf8' })) + ).then((svgStrs) => svgStrs.map((svgStr, i) => [iconsNames[i], parse(svgStr)])) + ) + .then((svgElsEntries) => + svgElsEntries.map((entry) => [ + entry[0], + { + innerHtml: entry[1].firstChild.innerHTML, + viewBox: entry[1].firstChild.getAttribute('viewBox'), + }, + ]) + ) + .then((cacheEntries) => Object.fromEntries(cacheEntries)) + .then((svgsObj) => fs.writeFile(destCachePath, formatCache(svgsObj))) + .then(resolve) + .catch(reject); + }); }; /** @@ -48,11 +48,11 @@ module.exports = function extractSVGs() { * @returns Cache file contents. */ function formatCache(obj) { - const declaration = `const cache = `; - const cacheObj = JSON.stringify(obj); - const bottomExport = `export default cache;`; + const declaration = `const cache = `; + const cacheObj = JSON.stringify(obj); + const bottomExport = `export default cache;`; - const fileContents = `${declaration}${cacheObj}\n\n${bottomExport}`; + const fileContents = `${declaration}${cacheObj}\n\n${bottomExport}`; - return fileContents; + return fileContents; } diff --git a/src/main.js b/src/main.js index bf9bb1d..4f59c49 100644 --- a/src/main.js +++ b/src/main.js @@ -13,9 +13,9 @@ import iconsCache from './iconsCache'; const iconSelector = '.js-navigation-container > .js-navigation-item'; observe(iconSelector, { - add(row) { - replaceIcon(row, iconMap); - }, + add(row) { + replaceIcon(row, iconMap); + }, }); /** @@ -28,29 +28,29 @@ observe(iconSelector, { * @returns Replace icon with material icon. */ function replaceIcon(fileRow, iconMap) { - // get file/folder name. - const fileName = fileRow.querySelector('[role=rowheader]')?.firstElementChild?.firstElementChild - ?.innerText; - if (!fileName) return; // fileName couldn't be found or we don't have a match for it. + // get file/folder name. + const fileName = + fileRow.querySelector('[role=rowheader]')?.firstElementChild?.firstElementChild?.innerText; + if (!fileName) return; // fileName couldn't be found or we don't have a match for it. - // svg to be replaced. - const svgEl = fileRow.querySelector('.octicon'); - if (!svgEl) return; // couldn't find svg element. + // svg to be replaced. + const svgEl = fileRow.querySelector('.octicon'); + if (!svgEl) return; // couldn't find svg element. - // get Directory or File type. - const isDir = svgEl.getAttribute('aria-label') === 'Directory'; + // get Directory or File type. + const isDir = svgEl.getAttribute('aria-label') === 'Directory'; - // get icon filename. - const iconName = lookForMatch(fileName, isDir, iconMap); // returns iconname if found or undefined. - if (!iconName) return; + // get icon filename. + const iconName = lookForMatch(fileName, isDir, iconMap); // returns iconname if found or undefined. + if (!iconName) return; - const { innerHtml, viewBox } = iconsCache[iconName + '.svg']; - if (!innerHtml || !viewBox) return; + const { innerHtml, viewBox } = iconsCache[iconName + '.svg']; + if (!innerHtml || !viewBox) return; - // must first reset innerHTML on svgEl to innerHTML of our svg. - svgEl.innerHTML = innerHtml; - // then must set viewBox on svgEl to viewBox on our icon. - svgEl.setAttribute('viewBox', viewBox); + // must first reset innerHTML on svgEl to innerHTML of our svg. + svgEl.innerHTML = innerHtml; + // then must set viewBox on svgEl to viewBox on our icon. + svgEl.setAttribute('viewBox', viewBox); } /** @@ -64,24 +64,24 @@ function replaceIcon(fileRow, iconMap) { * @returns the matched icon name. */ function lookForMatch(fileName, isDir, iconMap) { - // returns icon name string if matches otherwise undefined. - const lowerFileName = fileName.toLowerCase(); - // first look in fileNames and folderNames. - if (iconMap.fileNames[fileName] && !isDir) return iconMap.fileNames[fileName]; - if (iconMap.folderNames[fileName] && isDir) return iconMap.folderNames[fileName]; + // returns icon name string if matches otherwise undefined. + const lowerFileName = fileName.toLowerCase(); + // first look in fileNames and folderNames. + if (iconMap.fileNames[fileName] && !isDir) return iconMap.fileNames[fileName]; + if (iconMap.folderNames[fileName] && isDir) return iconMap.folderNames[fileName]; - // then check all lowercase. - if (iconMap.fileNames[lowerFileName] && !isDir) return iconMap.fileNames[lowerFileName]; - if (iconMap.folderNames[lowerFileName] && isDir) return iconMap.folderNames[lowerFileName]; + // then check all lowercase. + if (iconMap.fileNames[lowerFileName] && !isDir) return iconMap.fileNames[lowerFileName]; + if (iconMap.folderNames[lowerFileName] && isDir) return iconMap.folderNames[lowerFileName]; - // look for extension in fileExtensions and languageIds. - const captureExtension = /.+(?<=\.)(.+)$/; - const extension = fileName.match(captureExtension)?.[1]; + // look for extension in fileExtensions and languageIds. + const captureExtension = /.+(?<=\.)(.+)$/; + const extension = fileName.match(captureExtension)?.[1]; - if (iconMap.fileExtensions[extension] && !isDir) return iconMap.fileExtensions[extension]; - if (iconMap.languageIds[extension] && !isDir) return iconMap.languageIds[extension]; + if (iconMap.fileExtensions[extension] && !isDir) return iconMap.fileExtensions[extension]; + if (iconMap.languageIds[extension] && !isDir) return iconMap.languageIds[extension]; - // fallback into default file or folder if no matches. - if (!isDir) return 'file'; - if (isDir) return 'folder'; + // fallback into default file or folder if no matches. + if (!isDir) return 'file'; + if (isDir) return 'folder'; } diff --git a/src/manifest.json b/src/manifest.json index 28022f0..05dd1de 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -1,24 +1,24 @@ { - "name": "Material Icons for Github", - "version": "1.0.0", - "manifest_version": 2, - "description": "Replace the file/folder icons on the GitHub file browser with icons representing the file's type and which tool it is used by.", - "homepage_url": "https://github.com/Claudiohbsantos/github-material-icons-extension", - "icons": { - "16": "icons/icon16.png", - "32": "icons/icon32.png", - "48": "icons/icon48.png", - "128": "icons/icon128.png" - }, - "content_scripts": [ - { - "matches": [ - "*://*.github.com/*" - ], - "js": [ - "./main.js" - ], - "run_at": "document_start" - } - ] + "name": "Material Icons for Github", + "version": "1.0.0", + "manifest_version": 2, + "description": "Replace the file/folder icons on the GitHub file browser with icons representing the file's type and which tool it is used by.", + "homepage_url": "https://github.com/Claudiohbsantos/github-material-icons-extension", + "icons": { + "16": "icons/icon16.png", + "32": "icons/icon32.png", + "48": "icons/icon48.png", + "128": "icons/icon128.png" + }, + "content_scripts": [ + { + "matches": [ + "*://*.github.com/*" + ], + "js": [ + "./main.js" + ], + "run_at": "document_start" + } + ] }