Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
reactive
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Кубота
reactive
Commits
e3ee0cb1
Commit
e3ee0cb1
authored
Jun 05, 2019
by
Иван Кубота
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Split components.
Clone objects tree with cloning reactive subscriptions. WeakMap shim
parent
31813a8d
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
238 additions
and
133 deletions
+238
-133
F.js
src/F.js
+92
-12
Button.tsx
src/cmp/Button.tsx
+10
-14
Slider.jsx
src/cmp/Slider.jsx
+83
-0
UIComponent.jsx
src/cmp/UIComponent.jsx
+27
-0
index.jsx
src/index.jsx
+26
-107
No files found.
src/F.js
View file @
e3ee0cb1
...
@@ -5,7 +5,45 @@ const emptyFn = ()=>void 0;
...
@@ -5,7 +5,45 @@ const emptyFn = ()=>void 0;
const
falseFn
=
()
=>
false
;
const
falseFn
=
()
=>
false
;
const
REFLECTION
=
true
;
const
REFLECTION
=
true
;
const
WEAKMAP
=
typeof
WeakMap
===
'function'
;
if
(
typeof
Object
.
assign
===
'undefined'
){
Object
.
assign
=
function
(
a
,...
x
)
{
let
i
,
_i
=
x
.
length
,
o
,
key
;
for
(
i
=
0
;
i
<
_i
;
i
++
){
o
=
x
[
i
];
for
(
key
in
o
){
a
[
key
]
=
o
[
key
];
}
}
return
a
;
};
}
const
rand
=
()
=>
Math
.
random
().
toString
(
36
).
substr
(
2
);
const
WeakMapShim
=
function
()
{
this
.
_id
=
'__'
+
rand
();
this
.
store
=
{};
this
.
damaged
=
[];
};
WeakMapShim
.
prototype
=
{
get
:
function
(
a
)
{
return
this
.
store
[
a
[
this
.
_id
]];
},
has
:
function
(
a
)
{
return
a
.
hasOwnProperty
(
this
.
_id
)
&&
this
.
store
.
hasOwnProperty
(
a
[
this
.
_id
]);
},
set
:
function
(
a
,
b
)
{
let
key
=
rand
();
a
[
this
.
_id
]
=
key
;
this
.
store
[
key
]
=
b
;
this
.
damaged
.
push
(
a
);
},
clear
:
function
()
{
this
.
damaged
.
forEach
((
item
)
=>
delete
item
[
this
.
_id
]);
this
.
damaged
=
[];
this
.
store
=
{};
}
};
export
const
Reactivity
=
function
(
args
)
{
export
const
Reactivity
=
function
(
args
)
{
this
.
args
=
args
;
this
.
args
=
args
;
};
};
...
@@ -88,6 +126,9 @@ export const R = function() {
...
@@ -88,6 +126,9 @@ export const R = function() {
const
args
=
[];
const
args
=
[];
const
reactivity
=
new
Reactivity
(
args
);
const
reactivity
=
new
Reactivity
(
args
);
if
(
REFLECTION
){
reactivity
.
_deps
=
[];
}
for
(
let
i
=
0
,
_i
=
arguments
.
length
===
1
?
arguments
.
length
:
arguments
.
length
-
1
;
i
<
_i
;
i
++
){
for
(
let
i
=
0
,
_i
=
arguments
.
length
===
1
?
arguments
.
length
:
arguments
.
length
-
1
;
i
<
_i
;
i
++
){
const
obj
=
arguments
[
i
];
const
obj
=
arguments
[
i
];
if
(
typeof
obj
===
'function'
){
if
(
typeof
obj
===
'function'
){
...
@@ -98,6 +139,9 @@ export const R = function() {
...
@@ -98,6 +139,9 @@ export const R = function() {
reactivity
.
emit
();
reactivity
.
emit
();
};
};
args
[
i
]
=
objResolved
.
value
;
args
[
i
]
=
objResolved
.
value
;
if
(
REFLECTION
){
reactivity
.
_deps
[
i
]
=
objResolved
;
}
})
})
}
else
{
}
else
{
...
@@ -106,19 +150,16 @@ export const R = function() {
...
@@ -106,19 +150,16 @@ export const R = function() {
reactivity
.
emit
();
reactivity
.
emit
();
};
};
args
[
i
]
=
obj
.
value
;
args
[
i
]
=
obj
.
value
;
if
(
REFLECTION
){
reactivity
.
_deps
[
i
]
=
obj
;
}
}
}
}
}
if
(
arguments
.
length
===
1
){
if
(
arguments
.
length
===
1
){
reactivity
.
fn
=
byPass
;
reactivity
.
fn
=
byPass
;
if
(
REFLECTION
){
reactivity
.
_deps
=
[].
slice
.
call
(
arguments
);
}
}
else
{
}
else
{
reactivity
.
fn
=
arguments
[
arguments
.
length
-
1
];
reactivity
.
fn
=
arguments
[
arguments
.
length
-
1
];
if
(
REFLECTION
){
reactivity
.
_deps
=
[].
slice
.
call
(
arguments
,
0
,
arguments
.
length
-
1
);
}
}
}
return
reactivity
;
return
reactivity
;
...
@@ -151,6 +192,9 @@ ReactiveContent.prototype = {
...
@@ -151,6 +192,9 @@ ReactiveContent.prototype = {
}
else
{
}
else
{
throw
new
Error
(
'Fix it. My parent does not contain me (ReactiveChild)'
);
throw
new
Error
(
'Fix it. My parent does not contain me (ReactiveChild)'
);
}
}
},
clone
:
function
(
parent
)
{
return
new
ReactiveContent
(
parent
,
this
.
reactivity
);
}
}
};
};
...
@@ -267,7 +311,7 @@ Reactive.prototype = {
...
@@ -267,7 +311,7 @@ Reactive.prototype = {
beforeSetKey
:
function
(
key
,
val
,
lastVal
)
{
beforeSetKey
:
function
(
key
,
val
,
lastVal
)
{
return
val
;
return
val
;
},
},
_getReflectiveState
:
function
()
{
_getReflectiveState
:
function
(
cloningWorld
)
{
const
cloningState
=
{};
const
cloningState
=
{};
clone
(
this
.
state
,
cloningState
,
function
(
val
)
{
clone
(
this
.
state
,
cloningState
,
function
(
val
)
{
if
(
val
instanceof
Component
){
if
(
val
instanceof
Component
){
...
@@ -279,7 +323,12 @@ Reactive.prototype = {
...
@@ -279,7 +323,12 @@ Reactive.prototype = {
clone
(
this
.
_rState
,
cloningState
,
function
(
val
)
{
clone
(
this
.
_rState
,
cloningState
,
function
(
val
)
{
if
(
val
instanceof
Reactivity
){
if
(
val
instanceof
Reactivity
){
var
args
=
val
.
_deps
.
map
((
dep
)
=>
dep
.
obj
.
sub
(
dep
.
key
)).
concat
(
val
.
fn
);
var
args
=
val
.
_deps
.
map
(
function
(
dep
){
if
(
!
cloningWorld
.
has
(
dep
.
obj
)){
cloningWorld
.
set
(
dep
.
obj
,
new
dep
.
obj
.
_ctor
(
dep
.
obj
.
nodeName
));
}
return
cloningWorld
.
get
(
dep
.
obj
).
sub
(
dep
.
key
);
}).
concat
(
val
.
fn
);
console
.
log
(
val
,
args
)
console
.
log
(
val
,
args
)
return
R
.
apply
(
this
,
args
);
return
R
.
apply
(
this
,
args
);
...
@@ -532,16 +581,47 @@ Object.assign(Component.prototype, {
...
@@ -532,16 +581,47 @@ Object.assign(Component.prototype, {
this
.
set
(
this
.
def
);
this
.
set
(
this
.
def
);
this
.
_inited
=
true
;
this
.
_inited
=
true
;
},
},
clone
:
function
()
{
clone
:
function
(
cloningWorld
)
{
const
clone
=
new
this
.
_ctor
(
this
.
nodeName
);
if
(
cloningWorld
===
void
0
){
if
(
WEAKMAP
){
cloningWorld
=
new
WeakMap
();
}
else
{
cloningWorld
=
new
WeakMapShim
();
}
}
// CLONE OBJECT
let
clone
;
if
(
cloningWorld
.
has
(
this
)){
clone
=
cloningWorld
.
get
(
this
);
}
else
{
clone
=
new
this
.
_ctor
(
this
.
nodeName
);
cloningWorld
.
set
(
this
,
clone
);
}
clone
.
init
();
clone
.
init
();
// CLONE STRUCTURE
this
.
children
.
forEach
(
function
(
child
)
{
if
(
child
instanceof
ReactiveContent
){
clone
.
addChild
(
child
.
reactivity
);
}
else
{
clone
.
addChild
(
child
.
clone
(
cloningWorld
));
}
});
//TaskManager.add(function() {
// CLONE STATE
clone
.
_inited
=
false
;
if
(
REFLECTION
){
if
(
REFLECTION
){
clone
.
set
(
this
.
_getReflectiveState
(
)
);
clone
.
set
(
this
.
_getReflectiveState
(
cloningWorld
)
);
}
else
{
}
else
{
clone
.
set
(
this
.
state
);
clone
.
set
(
this
.
state
);
}
}
clone
.
_inited
=
true
;
//});
return
clone
;
return
clone
;
},
},
renderTo
:
function
(
where
)
{
renderTo
:
function
(
where
)
{
...
...
src/cmp/Button.tsx
View file @
e3ee0cb1
import
{
Component
,
h
,
PropSettersInterface
,
EventHandler
}
from
'../F'
;
import
{
Component
,
h
}
from
'../F'
;
interface
ButtonProps
{
onClick
:
EventHandler
<
MouseEvent
>
export
const
Button
=
Component
.
extend
(
'Button'
,
{
}
button
:
null
,
class
Button
extends
Component
<
ButtonProps
>
{
def
:
{
button
:
Component
=
null
;
def
=
{
type
:
'Button'
,
type
:
'Button'
,
disabled
:
false
disabled
:
false
}
;
}
,
setters
:
PropSettersInterface
<
Button
>
=
{
setters
:
{
value
:
(
_
,
val
:
string
)
=>
_
.
button
.
el
.
innerText
=
val
,
value
:
(
_
,
val
:
string
)
=>
_
.
button
.
el
.
innerText
=
val
,
disabled
:
(
_
,
val
:
boolean
)
=>
_
.
button
.
set
({
disabled
:
val
})
disabled
:
(
_
,
val
:
boolean
)
=>
_
.
button
.
set
({
disabled
:
val
})
}
;
}
,
render
(){
render
(){
//@ts-ignore
//@ts-ignore
this
.
button
=
<
button
/>;
this
.
button
=
<
button
/>;
return
this
.
button
;
return
this
.
button
;
}
}
}
});
\ No newline at end of file
export
{
Button
};
\ No newline at end of file
src/cmp/Slider.jsx
0 → 100644
View file @
e3ee0cb1
import
{
h
,
R
}
from
"../F"
;
import
{
UIComponent
}
from
'./UIComponent'
;
let
gg
=
0
;
export
const
Slider
=
UIComponent
.
extend
(
'Slider'
,
{
def
:
{
from
:
0
,
to
:
100
,
step
:
1
,
value
:
0
,
sliderWidth
:
10
,
background
:
'red'
,
mover
:
<
div
style=
{
{
cursor
:
'pointer'
,
width
:
10
,
height
:
10
,
/*R(but.sub('text'), (v1)=>{
if(gg<30){
console.log( v1 );
gg++;
}
return (v1-0)%20
})*/
border
:
'3px solid #fff'
,
position
:
'absolute'
,
boxSizing
:
'border-box'
}
}
/>
},
recalc
:
function
()
{
if
(
this
.
state
.
value
<
this
.
state
.
from
){
return
this
.
set
({
value
:
this
.
state
.
from
});
}
if
(
this
.
state
.
value
>
this
.
state
.
to
){
return
this
.
set
({
value
:
this
.
state
.
to
});
}
var
delta
=
this
.
state
.
to
-
this
.
state
.
from
;
this
.
state
.
mover
.
set
({
style
:
{
left
:
(
this
.
state
.
value
-
this
.
state
.
from
)
/
delta
*
(
this
.
state
.
width
-
this
.
state
.
sliderWidth
)
}
});
},
setters
:
{
'from,to,step,value,width'
:
(
_
)
=>
{
_
.
later
(
'recalc'
,
_
.
recalc
);
},
mover
:
function
(
_
,
val
,
lastVal
)
{
let
sliderRect
;
const
moveFn
=
(
e
)
=>
{
const
newRawVal
=
Math
.
max
(
0
,
Math
.
min
(
1
,(
e
.
clientX
-
sliderRect
.
left
)
/
(
sliderRect
.
width
))),
delta
=
this
.
state
.
to
-
this
.
state
.
from
,
newRangedVal
=
newRawVal
*
delta
+
this
.
state
.
from
,
step
=
this
.
state
.
step
,
newRoundedVal
=
Math
.
round
(
newRangedVal
/
step
)
*
step
;
this
.
set
({
value
:
newRoundedVal
});
};
//this.state.mover = ;
val
.
on
(
'mousedown'
,
(
e
)
=>
{
console
.
log
(
'down'
);
sliderRect
=
this
.
getBoundingClientRect
();
this
.
doc
.
on
(
'mousemove'
,
moveFn
);
this
.
doc
.
once
(
'mouseup'
,
()
=>
{
this
.
doc
.
un
(
'mousemove'
,
moveFn
);
});
this
.
set
({
width
:
sliderRect
.
width
});
e
.
preventDefault
();
});
}
},
render
(){
return
<
div
class=
"slider"
style=
{
{
background
:
R
(
this
.
sub
(
'background'
)),
position
:
'relative'
,
height
:
10
}
}
>
{
R
(
this
.
sub
(
'mover'
))
}
<
div
/>
</
div
>;
}
});
\ No newline at end of file
src/cmp/UIComponent.jsx
0 → 100644
View file @
e3ee0cb1
import
{
Component
}
from
"../F"
;
export
const
UIComponent
=
Component
.
extend
(
'UIComponent'
,
{
def
:
{
disabled
:
false
,
hidden
:
false
,
label
:
{
position
:
'top'
,
text
:
'Label'
},
selected
:
false
,
active
:
false
,
empty
:
false
,
placeholder
:
''
,
style
:
{
size
:
'normal'
,
margin
:
{
top
:
'16px'
}
}
},
setters
:
{
hidden
:
(
_
,
val
)
=>
_
.
el
.
style
.
display
=
val
===
false
?
'block'
:
'none'
,
style
:
(
_
,
val
)
=>
{
}
}
});
\ No newline at end of file
src/index.jsx
View file @
e3ee0cb1
import
{
Button
}
from
'./cmp/Button'
;
import
{
Button
}
from
'./cmp/Button'
;
import
{
h
,
R
,
Component
}
from
'./F'
;
import
{
h
,
R
,
Component
}
from
'./F'
;
let
i
,
btn
,
item
;
let
i
,
btn
,
item
;
import
{
UIComponent
}
from
"./cmp/UIComponent"
;
import
{
Slider
}
from
"./cmp/Slider"
;
c
lass
Item
extends
Component
{
c
onst
Item
=
Component
.
extend
(
'Item'
,
{
checkbox
=
null
;
checkbox
:
null
,
checkbox2
=
null
;
checkbox2
:
null
,
render
(){
render
(){
let
checkbox3
;
let
checkbox3
;
...
@@ -21,33 +23,10 @@ class Item extends Component {
...
@@ -21,33 +23,10 @@ class Item extends Component {
{
<
input
type=
"checkbox"
id=
"c4"
checked=
{
R
(
checkbox3
.
sub
(
'checked'
))
}
/>
}
<
br
/><
br
/><
br
/><
br
/>
{
<
input
type=
"checkbox"
id=
"c4"
checked=
{
R
(
checkbox3
.
sub
(
'checked'
))
}
/>
}
<
br
/><
br
/><
br
/><
br
/>
</
div
>;
</
div
>;
}
}
}
}
);
let
but
=
<
i
text=
{
2
}
>
1
</
i
>;
let
but
=
<
i
text=
{
2
}
>
1
</
i
>;
const
UIComponent
=
Component
.
extend
(
'UIComponent'
,
{
def
:
{
disabled
:
false
,
hidden
:
false
,
label
:
{
position
:
'top'
,
text
:
'Label'
},
selected
:
false
,
active
:
false
,
empty
:
false
,
placeholder
:
''
,
style
:
{
size
:
'normal'
,
margin
:
{
top
:
'16px'
}
}
},
setters
:
{
hidden
:
(
_
,
val
)
=>
_
.
el
.
style
.
display
=
val
===
false
?
'block'
:
'none'
,
style
:
(
_
,
val
)
=>
{
}
}
});
const
Check
=
UIComponent
.
extend
(
'Check'
,
{
const
Check
=
UIComponent
.
extend
(
'Check'
,
{
setters
:
{
setters
:
{
...
@@ -70,84 +49,7 @@ const Check = UIComponent.extend('Check', {
...
@@ -70,84 +49,7 @@ const Check = UIComponent.extend('Check', {
}
}
});
});
let
gg
=
0
;
const
Slider
=
UIComponent
.
extend
(
'Slider'
,
{
def
:
{
from
:
0
,
to
:
100
,
step
:
1
,
value
:
0
,
sliderWidth
:
10
,
background
:
'red'
,
mover
:
<
div
style=
{
{
cursor
:
'pointer'
,
width
:
10
,
height
:
R
(
but
.
sub
(
'text'
),
(
v1
)
=>
{
if
(
gg
<
30
){
console
.
log
(
v1
);
gg
++
;
}
return
(
v1
-
0
)
%
20
}),
border
:
'3px solid #fff'
,
position
:
'absolute'
,
boxSizing
:
'border-box'
}
}
/>
},
recalc
:
function
()
{
if
(
this
.
state
.
value
<
this
.
state
.
from
){
return
this
.
set
({
value
:
this
.
state
.
from
});
}
if
(
this
.
state
.
value
>
this
.
state
.
to
){
return
this
.
set
({
value
:
this
.
state
.
to
});
}
var
delta
=
this
.
state
.
to
-
this
.
state
.
from
;
this
.
state
.
mover
.
set
({
style
:
{
left
:
(
this
.
state
.
value
-
this
.
state
.
from
)
/
delta
*
(
this
.
state
.
width
-
this
.
state
.
sliderWidth
)
}
});
},
setters
:
{
'from,to,step,value,width'
:
(
_
)
=>
{
_
.
later
(
'recalc'
,
_
.
recalc
);
},
mover
:
function
(
_
,
val
,
lastVal
)
{
let
sliderRect
;
const
moveFn
=
(
e
)
=>
{
const
newRawVal
=
Math
.
max
(
0
,
Math
.
min
(
1
,(
e
.
clientX
-
sliderRect
.
left
)
/
(
sliderRect
.
width
))),
delta
=
this
.
state
.
to
-
this
.
state
.
from
,
newRangedVal
=
newRawVal
*
delta
+
this
.
state
.
from
,
step
=
this
.
state
.
step
,
newRoundedVal
=
Math
.
round
(
newRangedVal
/
step
)
*
step
;
this
.
set
({
value
:
newRoundedVal
});
};
//this.state.mover = ;
val
.
on
(
'mousedown'
,
(
e
)
=>
{
console
.
log
(
'down'
);
sliderRect
=
this
.
getBoundingClientRect
();
this
.
doc
.
on
(
'mousemove'
,
moveFn
);
this
.
doc
.
once
(
'mouseup'
,
()
=>
{
this
.
doc
.
un
(
'mousemove'
,
moveFn
);
});
this
.
set
({
width
:
sliderRect
.
width
});
e
.
preventDefault
();
});
}
},
render
(){
return
<
div
class=
"slider"
style=
{
{
background
:
R
(
this
.
sub
(
'background'
)),
position
:
'relative'
,
height
:
10
}
}
>
{
R
(
this
.
sub
(
'mover'
))
}
<
div
/>
</
div
>;
}
});
//
//
...
@@ -157,7 +59,14 @@ let slider1 = <Slider from={-10} to={100} step={1}/>;
...
@@ -157,7 +59,14 @@ let slider1 = <Slider from={-10} to={100} step={1}/>;
let
RS
,
GS
,
BS
;
let
RS
,
GS
,
BS
;
let
fr
,
tt
;
let
fr
,
tt
;
var
D
=
<
div
className=
'wrapper'
>
let
SSS
;
let
D
=
<
div
>
<
div
>
{
SSS
=
<
Slider
from=
{
0
}
to=
{
255
}
step=
{
1
}
value=
{
10
}
/>
}
<
span
text=
{
R
(
SSS
.
sub
(
'value'
))
}
/>
</
div
>
</
div
>;
D
=
<
div
className=
'wrapper'
>
<
div
text=
"text of div"
/><
div
>
text in div
</
div
>
<
div
text=
"text of div"
/><
div
>
text in div
</
div
>
<
Check
value=
{
true
}
label=
{
{
text
:
'Ti pidor'
}
}
hidden=
{
R
(()
=>
chhh
.
sub
(
'value'
))
}
/>
<
Check
value=
{
true
}
label=
{
{
text
:
'Ti pidor'
}
}
hidden=
{
R
(()
=>
chhh
.
sub
(
'value'
))
}
/>
{
chhh
}
{
chhh
}
...
@@ -195,7 +104,7 @@ var D = <div className='wrapper'>
...
@@ -195,7 +104,7 @@ var D = <div className='wrapper'>
(
b
)
=>
'rgba('
+
[
0
,
0
,
b
,
1
]
+
')'
(
b
)
=>
'rgba('
+
[
0
,
0
,
b
,
1
]
+
')'
)
}
/>
}
)
}
/>
}
<
div
style=
{
{
<
div
style=
{
{
width
:
300
,
height
:
300
,
height
:
300
,
padding
:
'30px'
,
padding
:
'30px'
,
position
:
'relative'
,
position
:
'relative'
,
...
@@ -236,7 +145,17 @@ var D = <div className='wrapper'>
...
@@ -236,7 +145,17 @@ var D = <div className='wrapper'>
`
)
}
/>
`
)
}
/>
</
div
>;
</
div
>;
//D.mount(document.body);
//
document
.
getElementById
(
'b1'
).
addEventListener
(
'click'
,
function
()
{
D
.
mount
(
document
.
getElementById
(
'd1'
));
});
document
.
getElementById
(
'b2'
).
addEventListener
(
'click'
,
function
()
{
var
G
=
D
.
clone
();
G
.
mount
(
document
.
getElementById
(
'd2'
));
});
setTimeout
(
function
()
{
document
.
getElementById
(
'b2'
).
click
();
},
30000
);
window
.
D
=
D
;
window
.
D
=
D
;
let
counter
=
0
;
let
counter
=
0
;
setInterval
(()
=>
{
setInterval
(()
=>
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment