Refactor code base for better enhancement and approach
11
.editorconfig
Normal 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
|
@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"extends": ["airbnb", "prettier"],
|
"extends": ["airbnb", "prettier"],
|
||||||
"plugins": ["prettier"],
|
"plugins": ["prettier"],
|
||||||
"rules": {
|
"rules": {
|
||||||
"prettier/prettier": ["error"]
|
"prettier/prettier": ["error"]
|
||||||
},
|
},
|
||||||
"globals": {
|
"globals": {
|
||||||
"window": true,
|
"window": true,
|
||||||
"document": true
|
"document": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
137
.gitignore
vendored
@ -1,125 +1,18 @@
|
|||||||
dist/
|
# Directories/files that may be generated by this project
|
||||||
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
|
|
||||||
dist
|
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/
|
.cache/
|
||||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
.vscode/
|
||||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
.DS_Store
|
||||||
# public
|
Thumbs.db
|
||||||
|
|
||||||
# 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.*
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"printWidth": 100,
|
"printWidth": 100,
|
||||||
"singleQuote": true
|
"singleQuote": true
|
||||||
}
|
}
|
||||||
|
3
.vscode/settings.json
vendored
@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"dimmer.enabled": false
|
|
||||||
}
|
|
4
LICENSE
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
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)
|
(MIT) Copyright (c) 2020 Philipp Kief (VSCode Material Icon Theme)
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
@ -19,4 +19,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
|
@ -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>
|
<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
|
### About
|
||||||
@ -42,13 +41,13 @@ Build only files from `src` folder, without re-downloading dependencies from [Ma
|
|||||||
npm run build-src
|
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
|
```shell
|
||||||
npm run rebuild-logos
|
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
|
```shell
|
||||||
npm run bundle
|
npm run bundle
|
||||||
|
BIN
assets/logo.png
Normal file
After Width: | Height: | Size: 17 KiB |
4949
package-lock.json
generated
86
package.json
@ -1,38 +1,52 @@
|
|||||||
{
|
{
|
||||||
"name": "material-icons-github-chrome-extension",
|
"name": "github-material-icons-extension",
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"description": "Chrome Extension that enhances the GitHub file browser with material icons",
|
"description": "Browser Extension that enhances the GitHub file browser with material icons.",
|
||||||
"main": "index.js",
|
"main": "src/main.js",
|
||||||
"scripts": {
|
"author": "Claudio Santos",
|
||||||
"build": "npx rimraf ./dist && npx run-s build-dependencies build-src bundle",
|
"license": "MIT",
|
||||||
"build-dependencies": "node ./scripts/build-dependencies.js",
|
"homepage": "https://github.com/Claudiohbsantos/github-material-icons-extension#readme",
|
||||||
"build-src": "node ./scripts/build-src.js",
|
"repository": {
|
||||||
"rebuild-logos": "node ./scripts/build-extensionIcons.js",
|
"type": "git",
|
||||||
"bundle": "run-p bundle-chrome bundle-firefox",
|
"url": "git+https://github.com/Claudiohbsantos/github-material-icons-extension.git"
|
||||||
"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",
|
"bugs": {
|
||||||
"parcel": "parcel build ./src/main.js"
|
"url": "https://github.com/Claudiohbsantos/github-material-icons-extension/issues"
|
||||||
},
|
},
|
||||||
"author": "",
|
"engines": {
|
||||||
"devDependencies": {
|
"node": ">=10.0.0",
|
||||||
"eslint": "^7.2.0",
|
"npm": ">=6.9.0 <7"
|
||||||
"eslint-config": "^0.3.0",
|
},
|
||||||
"eslint-config-airbnb": "^18.2.0",
|
"dependencies": {
|
||||||
"eslint-config-prettier": "^6.14.0",
|
"selector-observer": "2.1.6"
|
||||||
"eslint-plugin-prettier": "^3.1.4",
|
},
|
||||||
"fs-extra": "^9.0.1",
|
"devDependencies": {
|
||||||
"mkdirp": "^1.0.4",
|
"eslint": "7.29.0",
|
||||||
"node-html-parser": "^2.0.1",
|
"eslint-config": "0.3.0",
|
||||||
"npm-run-all": "^4.1.5",
|
"eslint-config-airbnb": "18.2.1",
|
||||||
"parcel-bundler": "^1.12.4",
|
"eslint-config-prettier": "8.3.0",
|
||||||
"prettier": "^2.1.2",
|
"eslint-plugin-prettier": "3.4.0",
|
||||||
"rimraf": "^3.0.2",
|
"fs-extra": "10.0.0",
|
||||||
"simple-git": "^2.31.0",
|
"mkdirp": "1.0.4",
|
||||||
"svgo": "^1.3.2",
|
"node-html-parser": "3.3.5",
|
||||||
"web-ext": "^5.5.0"
|
"npm-run-all": "4.1.5",
|
||||||
},
|
"parcel-bundler": "1.12.5",
|
||||||
"license": "ISC",
|
"prettier": "2.3.1",
|
||||||
"dependencies": {
|
"rimraf": "3.0.2",
|
||||||
"selector-observer": "^2.1.6"
|
"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"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,48 +1,43 @@
|
|||||||
const git = require('simple-git')();
|
/**
|
||||||
const child_process = require('child_process');
|
* External depedencies
|
||||||
|
*/
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const mkdirp = require('mkdirp');
|
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
|
const git = require('simple-git')();
|
||||||
|
const mkdirp = require('mkdirp');
|
||||||
const rimraf = require('rimraf');
|
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 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(vsExtPath);
|
||||||
rimraf.sync(destSVGPath);
|
rimraf.sync(destSVGPath);
|
||||||
mkdirp(destSVGPath)
|
mkdirp(destSVGPath)
|
||||||
.then(() => git.clone(`https://github.com/PKief/vscode-material-icon-theme.git`, 'temp'))
|
.then(() =>
|
||||||
.then(npmInstallExt)
|
git.clone(`https://github.com/PKief/vscode-material-icon-theme.git`, 'temp', ['--depth', '1'])
|
||||||
.then(() => fs.copy(path.resolve(vsExtPath, 'icons'), path.resolve(destSVGPath)))
|
)
|
||||||
.then(optimizeSVGs)
|
.then(() => child_process.execSync(`npm install`, vsExtExecOptions))
|
||||||
.then(npmBuildExt)
|
.then(() => fs.copy(path.resolve(vsExtPath, 'icons'), path.resolve(destSVGPath)))
|
||||||
.then(() =>
|
.then(() => child_process.exec(`npx svgo --disable=removeViewBox .`, distIconsExecOptions))
|
||||||
fs.copy(
|
.then(() => child_process.execSync(`npm run build`, vsExtExecOptions))
|
||||||
path.resolve(vsExtPath, 'dist', 'material-icons.json'),
|
.then(() =>
|
||||||
path.resolve(srcPath, 'iconMap.json')
|
fs.copy(
|
||||||
)
|
path.resolve(vsExtPath, 'dist', 'material-icons.json'),
|
||||||
)
|
path.resolve(srcPath, 'iconMap.json')
|
||||||
.then(() => rimraf.sync(vsExtPath))
|
)
|
||||||
////
|
)
|
||||||
|
.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);
|
|
||||||
}
|
|
||||||
|
@ -1,52 +1,33 @@
|
|||||||
// DEPENDS ON INKSCAPE 1.x on the PATH
|
/**
|
||||||
|
* External depedencies
|
||||||
// renders src/logo.svg to desired icon sizes for the extension
|
*/
|
||||||
const child_process = require('child_process');
|
|
||||||
const mkdirp = require('mkdirp');
|
|
||||||
const path = require('path');
|
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');
|
* Internal depedencies
|
||||||
const svgPath = path.resolve(srcPath, 'logo.svg');
|
*/
|
||||||
|
const svgPath = path.resolve(__dirname, '..', 'src', 'logo.svg');
|
||||||
|
const iconsPath = path.resolve(__dirname, '..', 'src', 'extensionIcons');
|
||||||
const targetSizes = [16, 32, 48, 128];
|
const targetSizes = [16, 32, 48, 128];
|
||||||
|
|
||||||
const execOptions = {
|
// Build extension icons.
|
||||||
cwd: extIconsPath,
|
mkdirp(iconsPath).then(generateIcons);
|
||||||
stdio: 'inherit',
|
|
||||||
};
|
|
||||||
|
|
||||||
// ensure inkscape 1.x is available
|
/**
|
||||||
child_process.exec('inkscape --version', execOptions, (error, stout) => {
|
* Generate extension icons.
|
||||||
if (error)
|
*
|
||||||
console.error(
|
* @since 1.4.0
|
||||||
`inkscape doesn't seem to be available. Make sure you have inkscape 1.0.1 or later installed on the PATH`
|
*/
|
||||||
);
|
function generateIcons() {
|
||||||
else {
|
targetSizes.map((size) => {
|
||||||
// check version
|
sharp(svgPath)
|
||||||
const versionRgx = /Inkscape (?<major>\d+).\d+.\d+/;
|
.png()
|
||||||
const major = versionRgx.exec(stout)?.groups?.major;
|
.resize({ width: size, height: size })
|
||||||
if (!major || +major < 1)
|
.toFile(`${iconsPath}/icon${size}.png`)
|
||||||
console.error(
|
.catch(function (err) {
|
||||||
`inkscape version is not compatible with this script. Make sure to install v1.x or later.`
|
console.log(err);
|
||||||
);
|
});
|
||||||
|
});
|
||||||
buildIcons();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
@ -1,41 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* External depedencies
|
||||||
|
*/
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const mkdirp = require('mkdirp');
|
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
|
const mkdirp = require('mkdirp');
|
||||||
const Parcel = require('parcel-bundler');
|
const Parcel = require('parcel-bundler');
|
||||||
const extractSVGs = require('./extract-svgHtml');
|
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 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 to dist.
|
||||||
|
mkdirp(distPath).then(createIconsCache).then(copySrc);
|
||||||
|
|
||||||
// copy src files
|
/**
|
||||||
|
* 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')
|
||||||
|
);
|
||||||
|
|
||||||
function src() {
|
// Copy extension icon.
|
||||||
const entryFile = path.resolve(srcPath, 'main.js');
|
const copyExtensionLogos = fs.copy(
|
||||||
const parcelOptions = {
|
path.resolve(srcPath, "extensionIcons"),
|
||||||
watch: false,
|
path.resolve(distPath, "icons")
|
||||||
minify: true,
|
);
|
||||||
};
|
|
||||||
const bundler = new Parcel(entryFile, parcelOptions);
|
|
||||||
const bundleMainScript = bundler.bundle();
|
|
||||||
|
|
||||||
const copyManifest = fs.copy(
|
// Bundle the main script.
|
||||||
path.resolve(srcPath, 'manifest.json'),
|
const entryFile = path.resolve(srcPath, 'main.js');
|
||||||
path.resolve(distPath, 'manifest.json')
|
const bundleMainScript = new Parcel(entryFile, {
|
||||||
);
|
watch: false,
|
||||||
|
minify: true,
|
||||||
|
}).bundle();
|
||||||
|
|
||||||
const copyExtensionLogos = fs.copy(path.resolve(srcPath, 'extensionIcons'), distPath);
|
return Promise.all([copyManifest, copyExtensionLogos, bundleMainScript]);
|
||||||
|
|
||||||
return Promise.all([copyManifest, copyExtensionLogos, bundleMainScript]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create icons cache.
|
||||||
|
*
|
||||||
|
* @since 1.4.0
|
||||||
|
*/
|
||||||
function createIconsCache() {
|
function createIconsCache() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
fs.copy(path.resolve(srcPath, 'customIcons'), destSVGPath)
|
fs.copy(path.resolve(srcPath, 'customIcons'), destSVGPath)
|
||||||
.then(() => extractSVGs())
|
.then(() => extractSVGs())
|
||||||
.then(resolve)
|
.then(resolve)
|
||||||
.catch(reject);
|
.catch(reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,40 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* External depedencies
|
||||||
|
*/
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require('fs').promises;
|
const fs = require('fs').promises;
|
||||||
const { parse } = require('node-html-parser');
|
const { parse } = require('node-html-parser');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the SVG elements.
|
||||||
|
*
|
||||||
|
* @since 1.4.0
|
||||||
|
*
|
||||||
|
* @returns a newly generated promise object.
|
||||||
|
*/
|
||||||
module.exports = function extractSVGs() {
|
module.exports = function extractSVGs() {
|
||||||
const iconsPath = path.resolve(__dirname, '..', 'optimizedSVGs');
|
const iconsPath = path.resolve(__dirname, '..', 'optimizedSVGs');
|
||||||
const destCachePath = path.resolve(__dirname, '..', 'src', 'iconsCache.js');
|
const destCachePath = path.resolve(__dirname, '..', 'src', 'iconsCache.js');
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
fs.readdir(iconsPath)
|
fs.readdir(iconsPath)
|
||||||
.then((iconsNames) =>
|
.then((iconsNames) =>
|
||||||
Promise.all(
|
Promise.all(
|
||||||
iconsNames.map((name) => fs.readFile(path.resolve(iconsPath, name), { encoding: 'utf8' }))
|
iconsNames.map((name) => fs.readFile(path.resolve(iconsPath, name), { encoding: 'utf8' }))
|
||||||
).then((svgStrs) => svgStrs.map((svgStr, i) => [iconsNames[i], parse(svgStr)]))
|
).then((svgStrs) => svgStrs.map((svgStr, i) => [iconsNames[i], parse(svgStr)]))
|
||||||
)
|
)
|
||||||
.then((svgElsEntries) =>
|
.then((svgElsEntries) =>
|
||||||
svgElsEntries.map((entry) => [
|
svgElsEntries.map((entry) => [
|
||||||
entry[0],
|
entry[0],
|
||||||
{
|
{
|
||||||
innerHtml: entry[1].firstChild.innerHTML,
|
innerHtml: entry[1].firstChild.innerHTML,
|
||||||
viewBox: entry[1].firstChild.getAttribute('viewBox'),
|
viewBox: entry[1].firstChild.getAttribute('viewBox'),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
.then((cacheEntries) => Object.fromEntries(cacheEntries))
|
.then((cacheEntries) => Object.fromEntries(cacheEntries))
|
||||||
.then((svgsObj) => fs.writeFile(destCachePath, formatCache(svgsObj)))
|
.then((svgsObj) => fs.writeFile(destCachePath, formatCache(svgsObj)))
|
||||||
.then(resolve)
|
.then(resolve)
|
||||||
.catch(reject);
|
.catch(reject);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format icons cache.
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*
|
||||||
|
* @param {*} obj SVG Object.
|
||||||
|
* @returns Cache file contents.
|
||||||
|
*/
|
||||||
function formatCache(obj) {
|
function formatCache(obj) {
|
||||||
const declaration = `const cache = `;
|
const declaration = `const cache = `;
|
||||||
const cacheObj = JSON.stringify(obj);
|
const cacheObj = JSON.stringify(obj);
|
||||||
const bottomExport = `export default cache;`;
|
const bottomExport = `export default cache;`;
|
||||||
|
|
||||||
const fileContents = `${declaration}${cacheObj}\n\n${bottomExport}`;
|
const fileContents = `${declaration}${cacheObj}\n\n${bottomExport}`;
|
||||||
|
|
||||||
return fileContents;
|
return fileContents;
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 558 B After Width: | Height: | Size: 730 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.5 KiB |
106
src/main.js
@ -1,61 +1,87 @@
|
|||||||
|
/**
|
||||||
|
* External depedencies
|
||||||
|
*/
|
||||||
import { observe } from 'selector-observer';
|
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';
|
const iconSelector = '.js-navigation-container > .js-navigation-item';
|
||||||
|
|
||||||
observe(iconSelector, {
|
observe(iconSelector, {
|
||||||
add(row) {
|
add(row) {
|
||||||
replaceIcon(row, iconMap);
|
replaceIcon(row, iconMap);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
function replaceIcon(fileRow, iconMap) {
|
||||||
// get file/folder name
|
// get file/folder name.
|
||||||
const fileName = fileRow.querySelector('[role=rowheader]')?.firstElementChild?.firstElementChild
|
const fileName = fileRow.querySelector('[role=rowheader]')?.firstElementChild?.firstElementChild
|
||||||
?.innerText;
|
?.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');
|
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';
|
const isDir = svgEl.getAttribute('aria-label') === 'Directory';
|
||||||
|
|
||||||
// get icon filename
|
// get icon filename.
|
||||||
const iconName = lookForMatch(fileName, isDir, iconMap); // returns iconname if found or undefined
|
const iconName = lookForMatch(fileName, isDir, iconMap); // returns iconname if found or undefined.
|
||||||
if (!iconName) return;
|
if (!iconName) return;
|
||||||
|
|
||||||
const { innerHtml, viewBox } = iconsCache[iconName + '.svg'];
|
const { innerHtml, viewBox } = iconsCache[iconName + '.svg'];
|
||||||
if (!innerHtml || !viewBox) return;
|
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;
|
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);
|
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) {
|
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();
|
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.fileNames[fileName] && !isDir) return iconMap.fileNames[fileName];
|
||||||
if (iconMap.folderNames[fileName] && isDir) return iconMap.folderNames[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.fileNames[lowerFileName] && !isDir) return iconMap.fileNames[lowerFileName];
|
||||||
if (iconMap.folderNames[lowerFileName] && isDir) return iconMap.folderNames[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 captureExtension = /.+(?<=\.)(.+)$/;
|
||||||
const extension = fileName.match(captureExtension)?.[1];
|
const extension = fileName.match(captureExtension)?.[1];
|
||||||
|
|
||||||
if (iconMap.fileExtensions[extension] && !isDir) return iconMap.fileExtensions[extension];
|
if (iconMap.fileExtensions[extension] && !isDir) return iconMap.fileExtensions[extension];
|
||||||
if (iconMap.languageIds[extension] && !isDir) return iconMap.languageIds[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 'file';
|
||||||
if (isDir) return 'folder';
|
if (isDir) return 'folder';
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,24 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 2,
|
"name": "Material Icons for Github",
|
||||||
"name": "Material Icons for Github",
|
"version": "1.0.0",
|
||||||
"version": "1.3",
|
"manifest_version": 2,
|
||||||
"description": "Replace the file/folder icons on github file browsers with icons representing the file's type and which tool it is used by.",
|
"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.",
|
||||||
"icons": {
|
"homepage_url": "https://github.com/Claudiohbsantos/github-material-icons-extension",
|
||||||
"16": "icon16.png",
|
"icons": {
|
||||||
"32": "icon32.png",
|
"16": "icons/icon16.png",
|
||||||
"48": "icon48.png",
|
"32": "icons/icon32.png",
|
||||||
"128": "icon128.png"
|
"48": "icons/icon48.png",
|
||||||
},
|
"128": "icons/icon128.png"
|
||||||
"content_scripts": [
|
},
|
||||||
{
|
"content_scripts": [
|
||||||
"matches": ["*://*.github.com/*"],
|
{
|
||||||
"js": ["./main.js"],
|
"matches": [
|
||||||
"run_at": "document_start"
|
"*://*.github.com/*"
|
||||||
}
|
],
|
||||||
],
|
"js": [
|
||||||
"homepage_url": "https://github.com/Claudiohbsantos/github-material-icons-extension"
|
"./main.js"
|
||||||
}
|
],
|
||||||
|
"run_at": "document_start"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|