Skip to content

Commit

Permalink
feat: init OOP
Browse files Browse the repository at this point in the history
  • Loading branch information
herrero-tranquilo committed Aug 22, 2021
1 parent 4eb1663 commit e1debfa
Show file tree
Hide file tree
Showing 8 changed files with 413 additions and 47 deletions.
5 changes: 4 additions & 1 deletion JS/.babelrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
{
"presets": ["@babel/preset-env"]
"presets": ["@babel/preset-env"],
"plugins": [
"@babel/plugin-proposal-class-properties"
]
}
3 changes: 1 addition & 2 deletions JS/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
"url": "https://github.com/k0603156/JSnPython/issues"
},
"dependencies": {
"-": "^0.0.1",
"D": "^1.0.0",
"chalk": "^4.0.0",
"eslint-scope": "^5.0.0",
"eslint-utils": "^1.4.2",
Expand All @@ -24,6 +22,7 @@
},
"devDependencies": {
"@babel/core": "^7.9.6",
"@babel/plugin-proposal-class-properties": "^7.8.3",
"@babel/preset-env": "^7.9.6",
"babel-loader": "^8.1.0",
"eslint": "^6.5.1",
Expand Down
16 changes: 8 additions & 8 deletions JS/scripts/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ const wp = require("webpack");

const wpConfigFactory = require("../webpack.config");

const [nodePath, selfPath, dirPath] = process.argv;

const buildPath = (relativePath) =>
path.resolve(fs.realpathSync(process.cwd()), relativePath);
const [nodePath, selfPath, dirName] = process.argv;

const buildPath = (dirname) => {
return path.resolve(fs.realpathSync(process.cwd()), './src/', dirname);
}
(async () => {
try {
if (!dirPath) {
throw Error("yan build --dirPath: dirPath가 존재하지 않습니다.");
if (!dirName) {
throw Error("yan build --dirName: dirName 존재하지 않습니다.");
}
wp(wpConfigFactory(buildPath(dirPath))).run();
wp(wpConfigFactory(buildPath(dirName))).run();
} catch (error) {
console.log(chalk.red(error));
console.error(chalk.red(error));
}
})();
15 changes: 15 additions & 0 deletions JS/src/objectOrientationProgramming/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<section id="target" data-viewmodel="wrapper">
<h2 data-viewmodel="title"></h2>
<section data-viewmodel="contents"></section>
</section>
</body>
</html>
77 changes: 77 additions & 0 deletions JS/src/objectOrientationProgramming/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
const { type, ViewModel, BinderItem, Binder, Processor, Scanner } = require("./util.js");

(() => {
const viewmodel = ViewModel.get({
changeContents() {
this.wrapper.styles.background = `rgb(
${parseInt(Math.random() * 150) + 100},
${parseInt(Math.random() * 150) + 100},
${parseInt(Math.random() * 150) + 100}
)`;
this.contents.properties.innerHTML = Math.random()
.toString(16)
.replace(".", "");
},
wrapper: ViewModel.get({
isStop: false,
styles: {
width: "50%",
background: "#ffa",
cursor: "pointer",
},
events: {
click(e, vm) {
vm.isStop = true;
},
},
}),
title: ViewModel.get({
properties: {
innerHTML: "Title",
},
}),
contents: ViewModel.get({
properties: {
innerHTML: "contents",
},
}),
});
const scanner = new Scanner();
const binder = scanner.scan(document.querySelector("#target"));

binder.addProcessor(
new (class extends Processor {
_process(vm, el, k, v) {
el.style[k] = v;
}
})("styles"),
);
binder.addProcessor(
new (class extends Processor {
_process(vm, el, k, v) {
el[k] = v;
}
})("properties"),
);
binder.addProcessor(
new (class extends Processor {
_process(vm, el, k, v) {
el.setAttribute(k, v);
}
})("attributes"),
);
binder.addProcessor(
new (class extends Processor {
_process(vm, el, k, v) {
el["on" + k] = (e) => v.call(el, e, vm);
}
})("events"),
);

const f = (_) => {
viewmodel.changeContents();
binder.render(viewmodel);
if (!viewmodel.wrapper.isStop) requestAnimationFrame(f);
};
requestAnimationFrame(f);
})();
128 changes: 128 additions & 0 deletions JS/src/objectOrientationProgramming/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
const type = (target, type) => {
if (typeof type == "string") {
if (typeof target != type)
throw TypeError(`invaild type ${target} : ${type}`);
} else if (!(target instanceof type))
throw TypeError(`invaild type ${target} : ${type}`);
return target;
};

const ViewModel = class {
static #private = Symbol();
static get(data) {
return new ViewModel(this.#private, data);
}
styles = {};
attributes = {};
properties = {};
events = {};
constructor(checker, data) {
if (checker != ViewModel.#private) throw "use ViewModel.get()";
Object.entries(data).forEach(([k, v]) => {
switch (k) {
case "styles":
this.styles = v;
break;
case "attributes":
this.attributes = v;
break;
case "properties":
this.properties = v;
break;
case "events":
this.events = v;
break;
default:
this[k] = v;
}
});
Object.seal(this);
}
};

const BinderItem = class {
el;
viewmodel;
constructor(
el,
viewmodel,
_0 = type(el, HTMLElement),
_1 = type(viewmodel, "string"),
) {
this.el = el;
this.viewmodel = viewmodel;
Object.freeze(this);
}
};

const Binder = class {
#items = new Set();
#processors = {};
add(v, _ = type(v, BinderItem)) {
this.#items.add(v);
}
addProcessor(v, _0 = type(v, Processor)) {
this.#processors[v.cat] = v;
}
render(viewmodel, _ = type(viewmodel, ViewModel)) {
const processores = Object.entries(this.#processors);
this.#items.forEach((item) => {
const vm = type(viewmodel[item.viewmodel], ViewModel), el = item.el;
processores.forEach(([pk, processor]) => {
Object.entries(vm[pk]).forEach(([k, v]) => {
processor.process(vm, el, k, v);
});
});
});
}
};

const Processor = class {
cat;
constructor(cat) {
this.cat = cat;
Object.freeze(this);
}
z;
process(
vm,
el,
k,
v,
_0 = type(vm, ViewModel),
_1 = type(el, HTMLElement),
_2 = type(k, "string"),
) {
this._process(vm, el, k, v);
}
_process(vm, el, k, v) {
throw "override";
}
};

const Scanner = class {
scan(el, _ = type(el, HTMLElement)) {
const binder = new Binder();
this.checkItem(binder, el);
const stack = [el.firstElementChild];
let target;
while ((target = stack.pop())) {
this.checkItem(binder, target);
if (target.firstElementChild) stack.push(target.firstElementChild);
if (target.nextElementSibling) stack.push(target.nextElementSibling);
}
return binder;
}
checkItem(binder, el) {
const vm = el.getAttribute("data-viewmodel");
if (vm) binder.add(new BinderItem(el, vm));
}
};

module.exports.type = type;

module.exports.ViewModel = ViewModel;
module.exports.BinderItem = BinderItem;
module.exports.Binder = Binder;
module.exports.Processor = Processor;
module.exports.Scanner = Scanner;
58 changes: 32 additions & 26 deletions JS/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

const paths = (buildPath) => ({
entry: path.resolve(buildPath, "index.js"),
output: {
filename: "main.js",
path: path.resolve(buildPath, "dist"),
},
htmlPluginOption: {
inject: true,
template: path.resolve(buildPath, "index.html"),
},
});
const paths = (buildDir) => {
console.log(path.resolve(buildDir, "index.js"));
return {
entry: path.resolve(buildDir, "index.js"),
output: {
filename: "main.js",
path: path.resolve(buildDir, "dist"),
},
htmlPluginOption: {
inject: true,
template: path.resolve(buildDir, "index.html"),
},
};
};

module.exports = (buildPath) => {
const { entry, output, htmlPluginOption } = paths(buildPath);
module.exports = (buildDir) => {
const { entry, output, htmlPluginOption } = paths(buildDir);
console.log(buildDir)
return {
entry,
output,
plugins: [new HtmlWebpackPlugin(htmlPluginOption)],
module: {
rules: [
{
test: [/\.js$/],
exclude: /node_modules/,
loader: require.resolve("babel-loader"),
},
],
},
};
entry,
output,
plugins: [new HtmlWebpackPlugin(htmlPluginOption)],
module: {
rules: [
{
test: [/\.js$/],
include: [buildDir],
exclude: /node_modules/,
loader: require.resolve("babel-loader"),
},
],
},
devtool: 'source-map',
};
};
Loading

0 comments on commit e1debfa

Please sign in to comment.