Commit 425328e8 by Иван Кубота

jsx support. cls reverse cb combinator feature. unknown props as attributes feature

parent 157731ed
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
<script src="js/view/page/products.js"></script> <script src="js/view/page/products.js"></script>
<script src="js/view/page/export.jsx"></script> <script src="js/view/page/export.jsx"></script>
<script src="js/view/page/generate.js"></script> <script src="js/view/page/generate.jsx"></script>
<script src="js/view/page/components.js"></script> <script src="js/view/page/components.js"></script>
<script src="js/controller/exportLogic.js"></script> <script src="js/controller/exportLogic.js"></script>
......
...@@ -36,36 +36,53 @@ router.all('/', function(req, res) { ...@@ -36,36 +36,53 @@ router.all('/', function(req, res) {
var path = require('path'); var path = require('path');
var cache = {}; var cache = {};
app.use(function (req, res, next) { var bCore = require( "@babel/core" );
var jsxServe = function(dir) {
return function (req, res, next) {
if (req.url in cache) { if (req.url in cache) {
return res.end(cache[req.url]) return res.end(cache[req.url])
}
if (req.url.substr(-8) === '.jsx.map') {
debugger
} }
/*if (req.url.substr(-8) === '.jsx.map') {
debugger
}*/
if (req.url.substr(-4) === '.jsx') { if (req.url.substr(-4) === '.jsx') {
fs.readFile(path.join(dir, req.url), function(err, data){
require("@babel/core").transform( debugger
fs.readFileSync('./public/js/view/page/export.jsx'), if( err ){
next();
}else{
bCore.transform(
data+'',
{ {
"plugins": [ "plugins": [
["@babel/plugin-transform-react-jsx", { [ "@babel/plugin-transform-react-jsx", {
"pragma": "D.h", // default pragma is React.createElement "pragma": "D.h", // default pragma is React.createElement
"pragmaFrag": "D.f", // default is React.Fragment "pragmaFrag": "D.f", // default is React.Fragment
"throwIfNamespace": false // defaults to true "throwIfNamespace": false // defaults to true
}] } ]
], ],
sourceMaps: 'both', sourceMaps: 'both',
sourceFileName: '/js/view/page/export.jsx' sourceFileName: req.url
}, function (c, d, e) { }, function( c, d, e ){
cache['/js/view/page/export.jsx.map'] = JSON.stringify(d.map); if(c){
res.set('SourceMap', '/js/view/page/export.jsx.map'); res.end(c.message+'\n'+c.stack)
res.end(d.code) }else{
}); debugger
cache[ req.url + '.map' ] = JSON.stringify( d.map );
res.set( 'SourceMap', req.url + '.map' );
res.end( d.code )
}
} );
}
});
} else { } else {
next(); next();
} }
}); }
};
app.use(jsxServe('public'));
app.use(App.static('public')) app.use(App.static('public'))
app.use('/', function(req, res) { app.use('/', function(req, res) {
res.end(print(JSON.stringify(data))); res.end(print(JSON.stringify(data)));
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
if( el.tagName.toLowerCase() === 'svg' ){ if( el.tagName.toLowerCase() === 'svg' ){
el.setAttribute( 'class', cls ); el.setAttribute( 'class', cls );
}else{ }else{
el.className = cls; el.className = D.cls.apply(D, arguments);
} }
} }
}, },
...@@ -24,29 +24,47 @@ ...@@ -24,29 +24,47 @@
} }
}; };
var used = {
cls: true, className: true, 'class': true,
attr: true,
prop: true,
on: true
};
// ~jsx h function // ~jsx h function
var domEl = function( type, cfg ){ var domEl = function( type, cfg ){
cfg = cfg || {}; cfg = cfg || {};
var cls = cfg.cls, var cls = cfg.cls || cfg['class'] || cfg.className,
style = cfg.style, style = cfg.style,
attr = cfg.attr,
attr = cfg.attr || {},
prop = cfg.prop, prop = cfg.prop,
on = cfg.on, on = cfg.on || {},
renderTo = cfg.renderTo, renderTo = cfg.renderTo,
el = cfg.el || document.createElement( type ), el = cfg.el || document.createElement( type ),
classList = el.classList; classList = el.classList;
var i, _i; var i, _i, name;
for(i in cfg)
if( cfg.hasOwnProperty(i)){
name = i.toLowerCase();
if(name in used)
continue;
if(name.substr(0, 2) === 'on'){
on[ name.substr( 2 ) ] = cfg[ i ];
}else{
attr[i] = cfg[i];
}
}
if( cls ){ if( cls ){
if(typeof cls === 'function'){ if(typeof cls === 'function'){
cls(setters.cls(el)); cls(setters.cls(el));
}else{ }else{
if( el.tagName.toLowerCase() === 'svg' ){ setters.cls(el)(cls);
el.setAttribute( 'class', cls );
}else{
el.className = cls;
}
} }
//if(el.className !== cls)debugger //if(el.className !== cls)debugger
//cls.split( ' ' ).forEach( function( clsItem ){ classList.add( clsItem ); }); //cls.split( ' ' ).forEach( function( clsItem ){ classList.add( clsItem ); });
......
view.cmp.Menu = ({title, id, key, cls}) => view.cmp.Menu = ({title, id, key, cls}) =>
div({ div({
cls: update => store.equal( cls: _ => store.equal(key, id,
key, active => _( 'main-menu-item', cls,
id, 'main-menu-item__'+D.escapeCls(id),
active => update( {'main-menu-item__active':active}
D.cls( )),
'main-menu-item', onclick: ()=> store.set(key, id)
'main-menu-item__'+D.escapeCls(id),
cls,
{'main-menu-item__active':active}
)
)
),
on: {
click: ()=> store.set(key, id)}
}, title); }, title);
\ No newline at end of file
view.page.Export = function() { view.page.Export = function(){
this.dom = return <div cls="export-panel">
<div cls="export-panel"> <div cls="title-gradient">
<div cls="title-gradient"> <div cls="export-sub-menu">
<div cls="export-sub-menu"> <div cls="export-sub-menu">
<div cls="export-sub-menu"> {view.cmp.Menu( { title: 'Тэги', id: 'tags', key: 'exportData' } )}
{view.cmp.Menu({title: 'Тэги', id: 'tags', key: 'exportData'})} {view.cmp.Menu( { title: 'Связи', id: 'connections', key: 'exportData' } )}
{view.cmp.Menu({title: 'Связи', id: 'connections', key: 'exportData'})} </div>
</div>
<div cls="export-sub-menu"> <div cls="export-sub-menu">
{view.cmp.Menu({title: 'CSV', id: 'csv', key: 'exportFormat'})} {view.cmp.Menu( { title: 'CSV', id: 'csv', key: 'exportFormat' } )}
{view.cmp.Menu({title: 'JSON', id: 'json', key: 'exportFormat'})} {view.cmp.Menu( { title: 'JSON', id: 'json', key: 'exportFormat' } )}
{view.cmp.Menu({title: 'YAML', id: 'yaml', key: 'exportFormat'})} {view.cmp.Menu( { title: 'YAML', id: 'yaml', key: 'exportFormat' } )}
{view.cmp.Menu({title: 'SQL', id: 'sql', key: 'exportFormat'})} {view.cmp.Menu( { title: 'SQL', id: 'sql', key: 'exportFormat' } )}
</div>
</div> </div>
</div> </div>
{exportLogic(D.textarea({cls: 'export-data'}))}
<div cls="export-comment">Connetction type{'<Enum>'}: 0 — продукт, 1 — компонент`</div>
<button on={{click:(e)=>{console.log(e)}}}>btn</button>
</div> </div>
{exportLogic( D.textarea( { cls: 'export-data' } ) )}
<div cls="export-comment">Connetction type{'<Enum>'}: 0 — продукт, 1 — компонент`</div>
<button onclick={e => console.log( e )}>btn</button>
</div>
console.log(this.dom) }
}; \ No newline at end of file
\ No newline at end of file
/* view.page.Export = function() {
view.page.Export = function() { this.dom =
this.dom = div({cls: 'export-panel'},
div({cls: 'export-panel'}, div({cls: 'title-gradient'},
div({cls: 'title-gradient'}, div({cls: 'export-sub-menu'},
div({cls: 'export-sub-menu'}, div({cls: 'export-sub-menu'},
div({cls: 'export-sub-menu'}, view.cmp.Menu({title: 'Тэги', id: 'tags', key: 'exportData'}),
view.cmp.Menu({title: 'Тэги', id: 'tags', key: 'exportData'}), view.cmp.Menu({title: 'Связи', id: 'connections', key: 'exportData'})
view.cmp.Menu({title: 'Связи', id: 'connections', key: 'exportData'}) ),
),
div({cls: 'export-sub-menu'},
div({cls: 'export-sub-menu'}, view.cmp.Menu({title: 'CSV', id: 'csv', key: 'exportFormat'}),
view.cmp.Menu({title: 'CSV', id: 'csv', key: 'exportFormat'}), view.cmp.Menu({title: 'JSON', id: 'json', key: 'exportFormat'}),
view.cmp.Menu({title: 'JSON', id: 'json', key: 'exportFormat'}), view.cmp.Menu({title: 'YAML', id: 'yaml', key: 'exportFormat'}),
view.cmp.Menu({title: 'YAML', id: 'yaml', key: 'exportFormat'}), view.cmp.Menu({title: 'SQL', id: 'sql', key: 'exportFormat'}),
view.cmp.Menu({title: 'SQL', id: 'sql', key: 'exportFormat'}), )
) )
) ),
), exportLogic(D.textarea({cls: 'export-data'})),
exportLogic(D.textarea({cls: 'export-data'})), div({cls: 'export-comment'}, `Connetction type<Enum>: 0 — продукт, 1 — компонент`)
div({cls: 'export-comment'}, `Connetction type<Enum>: 0 — продукт, 1 — компонент`) );
);
};*/
view.page.Export = function () {
this.dom = D.h("div", {
cls: "export-panel"
}, D.h("div", {
cls: "title-gradient"
}, D.h("div", {
cls: "export-sub-menu"
}, D.h("div", {
cls: "export-sub-menu"
}, view.cmp.Menu({
title: 'Тэги',
id: 'tags',
key: 'exportData'
}), view.cmp.Menu({
title: 'Связи',
id: 'connections',
key: 'exportData'
})), D.h("div", {
cls: "export-sub-menu"
}, view.cmp.Menu({
title: 'CSV',
id: 'csv',
key: 'exportFormat'
}), view.cmp.Menu({
title: 'JSON',
id: 'json',
key: 'exportFormat'
}), view.cmp.Menu({
title: 'YAML',
id: 'yaml',
key: 'exportFormat'
}), view.cmp.Menu({
title: 'SQL',
id: 'sql',
key: 'exportFormat'
})))), exportLogic(D.textarea({
cls: 'export-data'
})), D.h("div", {
cls: "export-comment"
}, "Connetction type", '<Enum>', ": 0 \u2014 \u043F\u0440\u043E\u0434\u0443\u043A\u0442, 1 \u2014 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442`"));
}; };
\ No newline at end of file
view.cmp.Answer = function(answer, type) {
return (
<label cls={D.cls('quiz-answer-label', 'quiz-answer-label__'+type)}>
<input type={type} checked={answer.correct}/>{answer.text}
</label>
)
};
view.page.Generate = function() {
const update = function() {
const photo = store.get('generatePhoto') === 'photo',
type = store.get('generateType'),
category = store.get('generateCategory');
try{
seedInput.value = Math.random.seeded.getStringSeed();
const result = category === 'product' ? quizGenerator( type, photo ) : standardGenerator(({length})=>rand(0,length-1));
title.innerHTML = textFormat( result.question, true );
image.innerHTML = result.image ? `<img src="${result.image}" alt="img"/>` : '';
image.style.display = result.image ? 'block': 'none';
debug.value = result.log.join( '\n' )
D.removeChildren( answers );
D.appendChild( answers, result.answers.map( ( a ) => view.cmp.Answer( a, type ) ) );
}catch( e ){
debug.value = quizGenerator.log.join( '\n' )
console.error(e)
}
};
let title, answers, debug, seedInput, image;
this.dom =
<div cls='generate-panel'>
<div cls='title-gradient'>
<div cls='generate-sub-menu'>
<div cls='generate-sub-menu'>
{view.cmp.Menu({title: 'Продукты', id: 'product', key: 'generateCategory'})}
{view.cmp.Menu({title: 'Стандарты', id: 'standard', key: 'generateCategory'})}
</div>
{view.cmp.Switch({key: 'generateCategory'}, {
product: <div cls='generate-sub-menu'>
<div cls='generate-sub-menu'>
{view.cmp.Menu({title: 'Единственный', id: 'radio', key: 'generateType'})}
{view.cmp.Menu({title: 'Множественный', id: 'checkbox', key: 'generateType'})}
</div>
<div cls='generate-sub-menu'>
{view.cmp.Menu({title: 'С фото', id: 'photo', key: 'generatePhoto'})}
{view.cmp.Menu({title: 'Без фото', id: 'noPhoto', key: 'generatePhoto'})}
</div>
</div>
})}
</div>
</div>
<div cls='generate-controls'>
<input type='button' value='F5' onclick={update}/>
<span cls='generate-seed-label'>Seed:</span>
{seedInput = <input
cls='seed'
type='input' value='' placeholder='seed'
oninput={function() {
var val = seedInput.value;
Math.random.seeded.setStringSeed(val);
update()
}}/>
}
</div>
<div cls='generate-example'>
{title = <div cls='generate-title'/>}
{image = <div cls='generate-image'/>}
{answers = <div cls='generate-answers'/>}
{debug = <textarea cls='generate-debug'/>}
</div>
</div>;
store.sub(['generateType', 'generatePhoto', 'generateCategory'], update);
};
\ No newline at end of file
view.cmp.Answer = function(answer, type) { view.cmp.Answer = function(answer, type) {
return D.label({cls: D.cls('quiz-answer-label', 'quiz-answer-label__'+type)}, return D.label({cls: D.cls('quiz-answer-label', 'quiz-answer-label__'+type)},
D.input({ D.input({
attr: {type, checked: answer.correct} attr: {type, checked: answer.correct}
}), }),
answer.text answer.text
) )
}; };
view.page.Generate = function() { view.page.Generate = function() {
const update = function() { const update = function() {
const photo = store.get('generatePhoto') === 'photo', const photo = store.get('generatePhoto') === 'photo',
type = store.get('generateType'), type = store.get('generateType'),
category = store.get('generateCategory'); category = store.get('generateCategory');
try{ try{
seedInput.value = Math.random.seeded.getStringSeed(); seedInput.value = Math.random.seeded.getStringSeed();
const result = category === 'product' ? quizGenerator( type, photo ) : standardGenerator(({length})=>rand(0,length-1)); const result = category === 'product' ? quizGenerator( type, photo ) : standardGenerator(({length})=>rand(0,length-1));
title.innerHTML = textFormat( result.question, true ); title.innerHTML = textFormat( result.question, true );
image.innerHTML = result.image ? `<img src="${result.image}" alt="img"/>` : ''; image.innerHTML = result.image ? `<img src="${result.image}" alt="img"/>` : '';
image.style.display = result.image ? 'block': 'none'; image.style.display = result.image ? 'block': 'none';
debug.value = result.log.join( '\n' ) debug.value = result.log.join( '\n' )
D.removeChildren( answers ); D.removeChildren( answers );
D.appendChild( answers, result.answers.map( ( a ) => view.cmp.Answer( a, type ) ) ); D.appendChild( answers, result.answers.map( ( a ) => view.cmp.Answer( a, type ) ) );
}catch( e ){ }catch( e ){
debug.value = quizGenerator.log.join( '\n' ) debug.value = quizGenerator.log.join( '\n' )
console.error(e) console.error(e)
} }
}; };
let title, answers, debug, seedInput, image; let title, answers, debug, seedInput, image;
this.dom = this.dom =
div({cls: 'generate-panel'}, div({cls: 'generate-panel'},
div({cls: 'title-gradient'}, div({cls: 'title-gradient'},
div({cls: 'generate-sub-menu'}, div({cls: 'generate-sub-menu'},
div({cls: 'generate-sub-menu'}, div({cls: 'generate-sub-menu'},
view.cmp.Menu({title: 'Продукты', id: 'product', key: 'generateCategory'}), view.cmp.Menu({title: 'Продукты', id: 'product', key: 'generateCategory'}),
view.cmp.Menu({title: 'Стандарты', id: 'standard', key: 'generateCategory'}) view.cmp.Menu({title: 'Стандарты', id: 'standard', key: 'generateCategory'})
), ),
view.cmp.Switch({key: 'generateCategory'}, { view.cmp.Switch({key: 'generateCategory'}, {
product: div({cls: 'generate-sub-menu'}, product: div({cls: 'generate-sub-menu'},
div({cls: 'generate-sub-menu'}, div({cls: 'generate-sub-menu'},
view.cmp.Menu({title: 'Единственный', id: 'radio', key: 'generateType'}), view.cmp.Menu({title: 'Единственный', id: 'radio', key: 'generateType'}),
view.cmp.Menu({title: 'Множественный', id: 'checkbox', key: 'generateType'}) view.cmp.Menu({title: 'Множественный', id: 'checkbox', key: 'generateType'})
), ),
div({cls: 'generate-sub-menu'}, div({cls: 'generate-sub-menu'},
view.cmp.Menu({title: 'С фото', id: 'photo', key: 'generatePhoto'}), view.cmp.Menu({title: 'С фото', id: 'photo', key: 'generatePhoto'}),
view.cmp.Menu({title: 'Без фото', id: 'noPhoto', key: 'generatePhoto'}) view.cmp.Menu({title: 'Без фото', id: 'noPhoto', key: 'generatePhoto'})
) )
) )
}) })
) )
), ),
div({cls: 'generate-controls'}, div({cls: 'generate-controls'},
D.input({ D.input({
attr: {type: 'button', value: 'F5'}, attr: {type: 'button', value: 'F5'},
on: {click: update}}), on: {click: update}}),
span({cls: 'generate-seed-label'}, 'Seed:'), span({cls: 'generate-seed-label'}, 'Seed:'),
seedInput = D.input({ seedInput = D.input({
cls: 'seed', cls: 'seed',
attr: {type: 'input', value: '', placeholder: 'seed'}, attr: {type: 'input', value: '', placeholder: 'seed'},
on: {input: function() { on: {input: function() {
var val = seedInput.value var val = seedInput.value
Math.random.seeded.setStringSeed(val); Math.random.seeded.setStringSeed(val);
update() update()
//Math.random.seeded.setStringSeed(val); //Math.random.seeded.setStringSeed(val);
}}}), }}}),
), ),
div({cls: 'generate-example'}, div({cls: 'generate-example'},
title = div({cls: 'generate-title'}), title = div({cls: 'generate-title'}),
image = div({cls: 'generate-image'}), image = div({cls: 'generate-image'}),
answers = div({cls: 'generate-answers'}), answers = div({cls: 'generate-answers'}),
debug = D.textarea({cls: 'generate-debug'}) debug = D.textarea({cls: 'generate-debug'})
) )
); );
store.sub(['generateType', 'generatePhoto', 'generateCategory'], update); store.sub(['generateType', 'generatePhoto', 'generateCategory'], update);
}; };
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment