Skip to content

Instantly share code, notes, and snippets.

@kujyp
Last active November 20, 2018 18:35
Show Gist options
  • Save kujyp/acef2e8c6b759a5b0b1073e7a36710e8 to your computer and use it in GitHub Desktop.
Save kujyp/acef2e8c6b759a5b0b1073e7a36710e8 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<img id="a">
<section id="b"></section>
<br/>
<br/>
<br/>
<section id="c"></section>
</body>
<script src="utils.js"></script>
<script src="Parser.js"></script>
<script src="Github.js"></script>
<script src="Loader.js"></script>
<script src="Repo.js"></script>
<script src="ImageParser.js"></script>
<script src="MdParser.js"></script>
<script src="TextParser.js"></script>
<script>
const loader = new Loader();
loader.addRepo('s75', 'hikaMaeng', 'codespitz75');
const img = new ImageParser('#a');
const md = new MdParser('#b');
loader.addRouter('s75', 'jpg,png,gif', img);
loader.addRouter('s75', 'md', md);
loader.load('s75', 'einBig.png');
loader.load('s75', 'README.md');
loader.addRepo('swe2022', 'hikaMaeng', 'swe2022');
const text = new TextParser('#c');
loader.addRouter('swe2022', 'java', text);
loader.load('swe2022', 'src/lesson3/Child.java');
</script>
</html>
const Github = class {
constructor(id, repo) {
this._base = `https://api.github.com/repos/${id}/${repo}/contents/`;
}
load(path) {
return new Promise((res, rej) => {
const id = 'callback' + Github._id++;
const f = Github[id] = ({data: { content }}) => {
delete Github[id];
document.head.removeChild(s);
res(content);
};
const s = document.createElement('script');
s.src = `${this._base + path}?callback=Github.${id}`;
document.head.appendChild(s);
});
}
};
Github._id = 0;
const ImageParser = class extends Parser {
parse(content) {
this._parent.src = 'data:text/plain;base64,' + content;
}
};
const getExtention = filename => {
return filename.substring(filename.lastIndexOf('.')+1, filename.length) || filename;
};
const Loader = class {
constructor() {
this._repo = new Map;
}
addRepo(key, id, repo) {
if (this._repo.has(key)) {
error(`Repo key [${key}] already exists.`);
return;
}
this._repo.set(key, new Repo(new Github(id, repo)))
}
addRouter(key, extentions, parser) {
if (!this._repo.has(key)) {
error(`Repo key [${key}] doesn't exist.`);
return;
}
const repo = this._repo.get(key);
extentions
.split(',')
.forEach(extention => repo.addParser(extention, parser));
}
load(repoKey, filename) {
if (!this._repo.has(repoKey)) {
error(`Call addRepo(${repoKey}, ...) first.`);
return;
}
const repo = this._repo.get(repoKey);
const extention = getExtention(filename);
if (!extention) {
error(`invalid extention. filename=[${filename}]`);
}
repo.parse(extention, filename)
}
};
const MdParser = class extends Parser {
_parseMD(v) {
return d64(v)
.split('\n')
.map(v => {
let i = 3;
while(i--) {
if(v.startsWith('#'.repeat(i + 1))) {
return `<h${i + 1}>${v.substr(i + 1)}</h${i + 1}>`;
}
}
return v;
})
.join('<br>');
}
parse(content) {
this._parent.innerHTML = this._parseMD(content);
}
};
const d64 = v => {
return decodeURIComponent(
atob(v)
.split('')
.map(c => '%' + ('00' +c.charCodeAt(0).toString(16)).slice(-2))
.join('')
);
};
const Parser = class {
constructor(parent) {
if (typeof parent != 'string' || !parent) {
error("invalid param");
}
this._parent = document.querySelector(parent);
}
parse(content) {
error("parse must overrided");
}
};
const Repo = class {
constructor(github) {
this._git = github;
this._router = new Map;
}
addParser(extention, parser) {
if (!extention) {
error(`invalid extention=[${extention}]`);
return;
}
if (!parser instanceof Parser) {
error(`invalid parser=[${parser}]`);
return;
}
if (this._router.has(extention)) {
error(`Parser of extention=[${extention}] already exists.`);
return;
}
this._router.set(extention, parser)
}
parse(extention, path) {
if (!this._router.has(extention)) {
error(`Extention [${extention}] parser doesn't exist.`);
return;
}
const parser = this._router.get(extention);
this._git.load(path)
.then(content => {
parser.parse(content);
})
.catch(err => {
error(`Git load failed. err=${err}`);
});
}
};
const TextParser = class extends Parser {
parse(content) {
this._parent.innerHTML = d64(content);
}
};
const error = (msg) => {
alert(msg);
throw msg;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment