Refactor code base for better enhancement and approach

This commit is contained in:
Shiva Poudel 2021-06-21 20:31:03 +05:45
parent ac7a61b395
commit de9a81baca
22 changed files with 3327 additions and 2338 deletions

11
.editorconfig Normal file
View File

@ -0,0 +1,11 @@
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = tab

137
.gitignore vendored
View File

@ -1,125 +1,18 @@
dist/
temp/
.vscode/
material-icons-github-chrome-extension.zip
material-icons-firefox-extension.zip
src/iconsCache.js
src/iconMap.json
optimizedSVGs/
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
# Directories/files that may be generated by this project
dist
temp
node_modules
optimizedSVGs
src/iconMap.json
src/iconsCache.js
material-icons-github-edge-extension.zip
material-icons-github-chrome-extension.zip
material-icons-github-firefox-extension.zip
# Gatsby files
# Directories/files that may appear in your environment
*.log
.idea
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
.vscode/
.DS_Store
Thumbs.db

2
.npmrc Normal file
View File

@ -0,0 +1,2 @@
save-exact = true
engine-strict = true

1
.nvmrc Normal file
View File

@ -0,0 +1 @@
lts/*

View File

@ -1,3 +0,0 @@
{
"dimmer.enabled": false
}

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2020 Claudio Santos and Richard Lam
Copyright (c) 2020 Claudio Santos, Shiva Poudel and Richard Lam
(MIT) Copyright (c) 2020 Philipp Kief (VSCode Material Icon Theme)
Permission is hereby granted, free of charge, to any person obtaining a copy

View File

@ -11,7 +11,6 @@
<b>Install directly from the <a href="https://chrome.google.com/webstore/detail/material-icons-for-github/bggfcpfjbdkhfhfmkjpbhnkhnpjjeomc">Chrome Web Store</a> or the <a href="https://addons.mozilla.org/en-US/firefox/addon/material-icons-for-github/">Addons for Firefox</a></b></div>
---
### About
@ -42,13 +41,13 @@ Build only files from `src` folder, without re-downloading dependencies from [Ma
npm run build-src
```
Rebuild extension logos from `src/logo.svg`. _This script needs [Inkscape](https://inkscape.org/) to be available on PATH_
Rebuild extension logos from `src/logo.svg`.
```shell
npm run rebuild-logos
```
Zip `dist` folder for upload to Chrome Web Store and Firefox. *This script needs 7z (7zip) to be available on PATH*
Zip `dist` folder for upload to Chrome Web Store and Firefox. _This script needs Zip to be available on PATH_
```shell
npm run bundle

BIN
assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

4931
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,38 +1,52 @@
{
"name": "material-icons-github-chrome-extension",
"name": "github-material-icons-extension",
"version": "1.3.0",
"description": "Chrome Extension that enhances the GitHub file browser with material icons",
"main": "index.js",
"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-chrome bundle-firefox",
"bundle-chrome": "7z a material-icons-github-chrome-extension.zip dist",
"bundle-firefox": "web-ext -s ./dist/ -n material-icons-firefox-extension.zip -a . build",
"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"
},
"author": "",
"devDependencies": {
"eslint": "^7.2.0",
"eslint-config": "^0.3.0",
"eslint-config-airbnb": "^18.2.0",
"eslint-config-prettier": "^6.14.0",
"eslint-plugin-prettier": "^3.1.4",
"fs-extra": "^9.0.1",
"mkdirp": "^1.0.4",
"node-html-parser": "^2.0.1",
"npm-run-all": "^4.1.5",
"parcel-bundler": "^1.12.4",
"prettier": "^2.1.2",
"rimraf": "^3.0.2",
"simple-git": "^2.31.0",
"svgo": "^1.3.2",
"web-ext": "^5.5.0"
},
"license": "ISC",
"dependencies": {
"selector-observer": "^2.1.6"
}
}

View File

@ -1,48 +1,43 @@
const git = require('simple-git')();
const child_process = require('child_process');
/**
* External depedencies
*/
const path = require('path');
const mkdirp = require('mkdirp');
const fs = require('fs-extra');
const git = require('simple-git')();
const mkdirp = require('mkdirp');
const rimraf = require('rimraf');
const child_process = require('child_process');
const destSVGPath = path.resolve(__dirname, '..', 'optimizedSVGs');
const vsExtPath = path.resolve(__dirname, '..', 'temp');
/**
* Internal depedencies
*/
const srcPath = path.resolve(__dirname, '..', 'src');
const vsExtPath = path.resolve(__dirname, '..', 'temp');
const destSVGPath = path.resolve(__dirname, '..', 'optimizedSVGs');
const vsExtExecOptions = {
cwd: vsExtPath,
stdio: 'inherit',
};
const distIconsExecOptions = {
cwd: path.resolve(destSVGPath),
stdio: 'inherit',
};
// Copy dependencies from vs code extension
// 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'))
.then(npmInstallExt)
.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(optimizeSVGs)
.then(npmBuildExt)
.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))
////
const vsExtExecOptions = {
cwd: vsExtPath,
stdio: 'inherit',
};
function npmInstallExt() {
child_process.execSync(`npm install`, vsExtExecOptions);
}
function npmBuildExt() {
child_process.execSync(`npm run build`, vsExtExecOptions);
}
const distIconsExecOptions = { cwd: path.resolve(destSVGPath), stdio: 'inherit' };
function optimizeSVGs() {
child_process.exec(`npx svgo --disable=removeViewBox .`, distIconsExecOptions);
}
.then(() => rimraf.sync(vsExtPath));

View File

@ -1,52 +1,33 @@
// DEPENDS ON INKSCAPE 1.x on the PATH
// renders src/logo.svg to desired icon sizes for the extension
const child_process = require('child_process');
const mkdirp = require('mkdirp');
/**
* External depedencies
*/
const path = require('path');
const sharp = require('sharp');
const mkdirp = require('mkdirp');
const extIconsPath = path.resolve(__dirname, '..', 'src', 'extensionIcons');
const srcPath = path.resolve(__dirname, '..', 'src');
const svgPath = path.resolve(srcPath, 'logo.svg');
/**
* Internal depedencies
*/
const svgPath = path.resolve(__dirname, '..', 'src', 'logo.svg');
const iconsPath = path.resolve(__dirname, '..', 'src', 'extensionIcons');
const targetSizes = [16, 32, 48, 128];
const execOptions = {
cwd: extIconsPath,
stdio: 'inherit',
};
// Build extension icons.
mkdirp(iconsPath).then(generateIcons);
// ensure inkscape 1.x is available
child_process.exec('inkscape --version', execOptions, (error, stout) => {
if (error)
console.error(
`inkscape doesn't seem to be available. Make sure you have inkscape 1.0.1 or later installed on the PATH`
);
else {
// check version
const versionRgx = /Inkscape (?<major>\d+).\d+.\d+/;
const major = versionRgx.exec(stout)?.groups?.major;
if (!major || +major < 1)
console.error(
`inkscape version is not compatible with this script. Make sure to install v1.x or later.`
);
buildIcons();
}
/**
* Generate extension icons.
*
* @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);
});
// build icons
function buildIcons() {
mkdirp(extIconsPath).then(Promise.all(targetSizes.map((size) => generateImage(svgPath, size))));
}
function generateImage(svgPath, size) {
return new Promise((resolve, reject) => {
child_process.exec(
`inkscape -h ${size} -w ${size} -o icon${size}.png ${svgPath}`,
execOptions,
(err, stout) => {
if (err) reject(err);
else resolve(stout);
}
);
});
}

View File

@ -1,36 +1,57 @@
/**
* External depedencies
*/
const path = require('path');
const mkdirp = require('mkdirp');
const fs = require('fs-extra');
const mkdirp = require('mkdirp');
const Parcel = require('parcel-bundler');
const extractSVGs = require('./extract-svgHtml');
const destSVGPath = path.resolve(__dirname, '..', 'optimizedSVGs');
const distPath = path.resolve(__dirname, '..', 'dist');
/**
* Internal depedencies
*/
const srcPath = path.resolve(__dirname, '..', 'src');
const distPath = path.resolve(__dirname, '..', 'dist');
const destSVGPath = path.resolve(__dirname, '..', 'optimizedSVGs');
mkdirp(distPath).then(createIconsCache).then(src);
// copy src files
function src() {
const entryFile = path.resolve(srcPath, 'main.js');
const parcelOptions = {
watch: false,
minify: true,
};
const bundler = new Parcel(entryFile, parcelOptions);
const bundleMainScript = bundler.bundle();
// copy src files to dist.
mkdirp(distPath).then(createIconsCache).then(copySrc);
/**
* Copy the src files.
*
* @since 1.4.0
*
* @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')
);
const copyExtensionLogos = fs.copy(path.resolve(srcPath, 'extensionIcons'), distPath);
// 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();
return Promise.all([copyManifest, copyExtensionLogos, bundleMainScript]);
}
/**
* Create icons cache.
*
* @since 1.4.0
*/
function createIconsCache() {
return new Promise((resolve, reject) => {
fs.copy(path.resolve(srcPath, 'customIcons'), destSVGPath)

View File

@ -1,7 +1,17 @@
/**
* External depedencies
*/
const path = require('path');
const fs = require('fs').promises;
const { parse } = require('node-html-parser');
/**
* Retrieve the SVG elements.
*
* @since 1.4.0
*
* @returns a newly generated promise object.
*/
module.exports = function extractSVGs() {
const iconsPath = path.resolve(__dirname, '..', 'optimizedSVGs');
const destCachePath = path.resolve(__dirname, '..', 'src', 'iconsCache.js');
@ -29,6 +39,14 @@ module.exports = function extractSVGs() {
});
};
/**
* Format icons cache.
*
* @since 1.0.0
*
* @param {*} obj SVG Object.
* @returns Cache file contents.
*/
function formatCache(obj) {
const declaration = `const cache = `;
const cacheObj = JSON.stringify(obj);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 558 B

After

Width:  |  Height:  |  Size: 730 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1,8 +1,15 @@
/**
* External depedencies
*/
import { observe } from 'selector-observer';
import iconsCache from './iconsCache';
import iconMap from './iconMap';
// run on load
/**
* Internal depedencies
*/
import iconMap from './iconMap';
import iconsCache from './iconsCache';
// Monitor DOM elements that match a CSS selector.
const iconSelector = '.js-navigation-container > .js-navigation-item';
observe(iconSelector, {
@ -11,51 +18,70 @@ observe(iconSelector, {
},
});
/**
* Replace file/folder icons.
*
* @since 1.0.0
*
* @param {*} fileRow File Row.
* @param {*} iconMap Icon Map.
* @returns Replace icon with material icon.
*/
function replaceIcon(fileRow, iconMap) {
// get file/folder name
// 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
if (!fileName) return; // fileName couldn't be found or we don't have a match for it.
// svg to be replaced
// svg to be replaced.
const svgEl = fileRow.querySelector('.octicon');
if (!svgEl) return; // couldn't find svg element
if (!svgEl) return; // couldn't find svg element.
// get type. Directory or File
// 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
// 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;
// must first reset innerHTML on svgEl to innerHTML of our svg
// 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
// then must set viewBox on svgEl to viewBox on our icon.
svgEl.setAttribute('viewBox', viewBox);
}
/**
* Lookup for matched icon name.
*
* @since 1.4.0
*
* @param {*} fileName File name.
* @param {*} isDir Check if directory or file type.
* @param {*} iconMap Icon map.
* @returns the matched icon name.
*/
function lookForMatch(fileName, isDir, iconMap) {
// returns icon name string if matches otherwise undefined
// returns icon name string if matches otherwise undefined.
const lowerFileName = fileName.toLowerCase();
// first look in fileNames and folderNames
// 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
// 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
// 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];
// fallback into default file or folder if no matches
// fallback into default file or folder if no matches.
if (!isDir) return 'file';
if (isDir) return 'folder';
}

View File

@ -1,20 +1,24 @@
{
"manifest_version": 2,
"name": "Material Icons for Github",
"version": "1.3",
"description": "Replace the file/folder icons on github file browsers with icons representing the file's type and which tool it is used by.",
"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": "icon16.png",
"32": "icon32.png",
"48": "icon48.png",
"128": "icon128.png"
"16": "icons/icon16.png",
"32": "icons/icon32.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"content_scripts": [
{
"matches": ["*://*.github.com/*"],
"js": ["./main.js"],
"matches": [
"*://*.github.com/*"
],
"js": [
"./main.js"
],
"run_at": "document_start"
}
],
"homepage_url": "https://github.com/Claudiohbsantos/github-material-icons-extension"
]
}