Slide 1

Slide 1 text

_ _ _ _ _ _ | _ _ ) _ _ _ _ _ _ | | _ _ | | _ _ _ _ | _ \ / _ ` | / _ _ | | / / | _ _ / _ \ | | _ ) | ( _ | | ( _ _ | < | | | ( _ ) | | _ _ _ _ / \ _ _ , _ | \ _ _ _ | _ | \ _ \ \ _ _ \ _ _ _ / | _ _ | _ _ _ _ _ | | _ | | | | _ _ | | | / _ \ \ / / _ _ | | | | | | | | | _ _ / > < | | _ | | _ | | | | | _ | \ _ _ _ / _ / \ _ \ \ _ _ | \ _ _ _ / | _ _ _ |

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

Writing, 3200 BCE

Slide 4

Slide 4 text

Woodblock printing, 200 AE

Slide 5

Slide 5 text

Printing press, 1440

Slide 6

Slide 6 text

Typewriter, 1860

Slide 7

Slide 7 text

Terminal, 70-80th

Slide 8

Slide 8 text

R e n d e r t e x t s ┌ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ┐ | D r a w T e x t U I | └ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ­ ┘ █ 8

Slide 9

Slide 9 text

. . . a n d f o r A S C I I A r t = = = = o o ~ ~ / ~ \ _ \ ­ / _ ( o o | _ _ _ / \ / \ _ \ = / _ / ( ) \ / / | | | \ \ / _ \ _ | _ _ _ _ _ | _ / / | | | / / = = = = = = = = = = = = = = = = = = = | | = = = | | / / | | / / | | | _ | O | _ | ( ' | = = = ( | | _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | | | O | | | | | | | | | | _ _ * _ _ | | ( _ ) ( _ ) | | | ~ \ _ _ _ / ~ | | _ | | _ | | | / = \ / = \ / = \ | _ | | _ | _ | _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | _ _ _ _ _ _ _ [ _ ] _ [ _ ] _ [ _ ] _ _ _ _ / _ _ ] [ _ _ \ _ _ 9

Slide 10

Slide 10 text

Text UI of Dired, 1974

Slide 11

Slide 11 text

Graphic UI, 1985

Slide 12

Slide 12 text

Window Art

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

GUI 1. Text UI – step in GUI evolution • PC for non-technical users 2. Browser APIs, WinAPI, GTK, Qt, ... • Easier to create GUI than TUI now 3. «Text UI is for hackers» 14

Slide 15

Slide 15 text

Developers <3 Terminal 1. Faster to type than click 2. Ability to compose text streams 3. More flexible than GUI 4. Less complicated than equal GUI 15

Slide 16

Slide 16 text

> w g e t ­ q O ­ f i l e | b s d t a r ­ x v f ­

Slide 17

Slide 17 text

Post GUI Text UI 1. Toolchain is not limited • 1-2 good libraries for every language 2. Imperative style 3. Range of DSV/DSL is a problem DSV – Domain Specific Vocabulary 17

Slide 18

Slide 18 text

Blessed.js Demo

Slide 19

Slide 19 text

Blessed.js v a r b o x = b l e s s e d . b o x ( { s t y l e : { f g: ' w h i t e ' , b g: ' m a g e n t a ' } , b o r d e r: { t y p e : ' l i n e ' } , t a g s : t r u e } ) ; 0 1 . 0 2 . 0 3 . 0 4 . 0 5 . 0 6 . 0 7 . 0 8 . 19

Slide 20

Slide 20 text

Simple lib – simple DSV i n q u i r e r . p r o m p t ( [ { t y p e : ' r a w l i s t ' , n a m e : ' t u i ' , m e s s a g e : ' A r e T U I s c o o l ? ' , c h o i c e s : [ ' Y u p ' , ' W h y d o y o u a s k ? ' ] } ] , ( a n s w e r s ) = > { } ) ; 0 1 . 0 2 . 0 3 . 0 4 . 0 5 . 0 6 . 0 7 . 20

Slide 21

Slide 21 text

Inquirer.js Demo

Slide 22

Slide 22 text

Creating UI engine is challenging 1. Layout Math • Relative positioning • Dynamic box dimensions 2. Simple yet familiar DSV • Naming, Structure, Styling, ... 22

Slide 23

Slide 23 text

23

Slide 24

Slide 24 text

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | | | | | | | | _ | | | | | | _ | | | _ _ | | | | | | | | | | | | | | | | | | | | | _ _ _ | _ | | | | | | _ | | | | | | _ _ | | _ _ | | _ _ _ | | _ | | _ | | _ _ _ _ _ _ _ | _ _ _ _ _ _ _ _ _ _ _ _ _ _ | | | | | | | | | _ _ | | | | | | | | | | | _ | | | | | | | | | | | | | | | |

Slide 25

Slide 25 text

< d i v s t y l e = " . . . " > C o n t e n t < / d i v >

Slide 26

Slide 26 text

┌ ­ ­ ­ ­ ­ ­ ­ ­ ­ ┐ | C o n t e n t | └ ­ ­ ­ ­ ­ ­ ­ ­ ­ ┘ █

Slide 27

Slide 27 text

< d i v s t y l e = " . . . " > A d v a n c e d < / d i v > < d i v s t y l e = " . . . " > L a y o u t < / d i v >

Slide 28

Slide 28 text

┌ ­ ­ ­ ­ ­ ­ ­ ­ ┐ ┌ ­ ­ ­ ­ ­ ­ ┐ | A d v a n c e d | | L a y o u t | └ ­ ­ ­ ­ ­ ­ ­ ­ ┘ └ ­ ­ ­ ­ ­ ­ ┘

Slide 29

Slide 29 text

< d i v c l a s s N a m e = " m c " > < u l c l a s s N a m e = " m e n u " > < l i c l a s s N a m e = " m e n u _ _ i t e m " > < s p a n c l a s s N a m e = " m e n u _ _ i t e m - s h o r t c < l i c l a s s N a m e = " m e n u _ _ i t e m " > < s p a n c l a s s N a m e = " m e n u _ _ i t e m - s h o r t c < l i c l a s s N a m e = " m e n u _ _ i t e m " > < s p a n c l a s s N a m e = " m e n u _ _ i t e m - s h o r t c < l i c l a s s N a m e = " m e n u _ _ i t e m " > < s p a n c l a s s N a m e = " m e n u _ _ i t e m - s h o r t c < l i c l a s s N a m e = " m e n u _ _ i t e m " > < s p a n c l a s s N a m e = " m e n u _ _ i t e m - s h o r t c < / u l > < d i v c l a s s N a m e = " c o n t e n t " > { t h i s . p r o p s . l e f t P a n e l ? t h i s . _ r e n d e r P a n e l ( t h i s . p r o p s . l e f t P a n e { t h i s . p r o p s . r i g h t P a n e l ? t h i s . _ r e n d e r P a n e l ( t h i s . p r o p s . r i g h t P a < / d i v > < d i v c l a s s N a m e = " c o n s o l e " > < i n p u t c l a s s N a m e = " c o n s o l e _ _ i n p u t " t y p e = " t e x t " d e f a u l t V a l u e = " ~ < / d i v > < u l c l a s s N a m e = " c o n t r o l s " > < l i c l a s s N a m e = " c o n t r o l " > < d i v c l a s s N a m e = " c o n t r o l _ _ n u m b e r " > 1 < / d i v > < d i v c l a s s N a m e = " c o n t r o l _ _ n a m e " > H e l p < / d i v > < / l i > < l i c l a s s N a m e = " c o n t r o l " > < d i v c l a s s N a m e = " c o n t r o l _ _ n u m b e r " > 2 < / d i v > < d i v c l a s s N a m e = " c o n t r o l _ _ n a m e " > M e n u < / d i v > < / l i > < l i c l a s s N a m e = " c o n t r o l " > 29

Slide 30

Slide 30 text

React Midnight Commander

Slide 31

Slide 31 text

Borrow from DOM API/CSSOM • e l e m . g e t C l i e n t R e c t s ( ) — Layout Math • g e t C o m p u t e d S t y l e ( e l e m ) — Styles • DOM Event system • Document Structure 31

Slide 32

Slide 32 text

< d i v s t y l e = " . . . " > C o n t e n t < / d i v >

Slide 33

Slide 33 text

9 P i x e l Content 3 p x

Slide 34

Slide 34 text

Translating
to TUI l e t s t y l e s = w i n d o w . g e t C o m p u t e d S t y l e ( d i v ) ; l e t r e c t = d i v . g e t C l i e n t R e c t s ( ) ; l e t b o x = r e n d e r B o x( r e c t , s t y l e s ) ; 0 1 . 0 2 . 0 3 . 34

Slide 35

Slide 35 text

9 S y m b o l s 3 s ┌ ­ ­ ­ ­ ­ ­ ­ ┐ | | └ ­ ­ ­ ­ ­ ­ ­ ┘

Slide 36

Slide 36 text

Translating textNode to TUI l e t s t y l e s = w i n d o w . g e t C o m p u t e d S t y l e ( d i v ) ; l e t t e x t = d i v . f i r s t C h i l d ; l e t r a n g e = d o c u m e n t . c r e a t e R a n g e ( ) ; r a n g e . s e l e c t N o d e C o n t e n t s ( t e x t ) ; l e t r e c t = r a n g e . g e t C l i e n t R e c t s ( ) ; l e t t e x t B o x = r e n d e r T e x t( r e c t , s t y l e s ) ; 0 1 . 0 2 . 0 3 . 0 4 . 0 5 . 0 6 . 36

Slide 37

Slide 37 text

9 S y m b o l s 3 s ┌ ­ ­ ­ ­ ­ ­ ­ ┐ | | └ ­ ­ ­ ­ ­ ­ ­ ┘ C o n t e n t

Slide 38

Slide 38 text

┌ ­ ­ ­ ­ ­ ­ ­ ┐ | | └ ­ ­ ­ ­ ­ ­ ­ ┘ C o n t e n t

Slide 39

Slide 39 text

DOM STDOUT →

Slide 40

Slide 40 text

STDIN DOM →

Slide 41

Slide 41 text

Forwarding Input events 1. Read from S T D I N 2. Serialize Event 3. Transmit to Browser 4. Replay on D O M 5. G O T O 1 41

Slide 42

Slide 42 text

No content

Slide 43

Slide 43 text

Ways of repainting 1. a d d E v e n t L i s t e n e r ( 'M o zA f t e r P a i n t ' ) 2. r e q u e s t A n i m a t i o n F r a m e ( ) • CPU burning 3. n e w M u t a t i o n O b s e r v e r ( ) • Only DOM changes 43

Slide 44

Slide 44 text

componentDidUpdate event bubbling?

Slide 45

Slide 45 text

No such thing!

Slide 46

Slide 46 text

Let's hack React!

Slide 47

Slide 47 text

ReactReconcileTransaction in a nutshell • Restores Selection after updates • Suppresses DOM events during updates • Source of c o m p o n e n t D i d U p d a t e 47

Slide 48

Slide 48 text

ON_DOM_READY_QUEUEING Transaction / / A q u e u e f o r c o l l e c t i n g ` c o m p o n e n t D i d M o u n t ` a n d / / ` c o m p o n e n t D i d U p d a t e ` c a l l b a c k s d u r i n g t r a n s a c t i o n v a r O N _ D O M _ R E A D Y _ Q U E U E I N G = { c l o s e : f u n c t i o n ( ) { t h i s . r e a c t M o u n t R e a d y .n o t i f y A l l( ) ; } / / . . . } ; 0 1 . 0 2 . 0 3 . 0 4 . 0 5 . 0 6 . 0 7 . 48

Slide 49

Slide 49 text

Hacking CallbackQueue c l a s s M y C Q e x t e n d s C a l l b a c k Q u e u e { n o t i f y A l l ( ) { s u p e r . n o t i f y A l l ( ) ; c o n s o l e . l o g ( ' u p d a t e ' ); } } P o o l e d C l a s s . a d d P o o l i n g T o ( M y C Q ) ; 0 1 . 0 2 . 0 3 . 0 4 . 0 5 . 0 6 . 0 7 . 49

Slide 50

Slide 50 text

Hacking ReactReconcileTransaction c l a s s M y R R T e x t e n d s R e a c t R e c o n c i l e T r a n s a c t i o n { c o n s t r u c t o r ( ) { s u p e r ( ) ; t h i s . r e a c t M o u n t R e a d y = M y C Q. g e t P o o l e d ( n u l l ) ; } } P o o l e d C l a s s . a d d P o o l i n g T o ( M y R R T ) ; R e a c t U p d a t e s . i n j e c t i o n . i n j e c t R e c o n c i l e T r a n s a c t i o n( M y R R T ) ; 0 1 . 0 2 . 0 3 . 0 4 . 0 5 . 0 6 . 0 7 . 0 8 . 0 9 . 50

Slide 51

Slide 51 text

Hacking ReactReconcileTransaction 1. Global React Tree changes • Close enough to AfterPaint 2. Requires o n W h e e l event hack 3. Doesn't help with stylesheet injections 51

Slide 52

Slide 52 text

Full Text UI Application Cycle 1. Measure D O M & generate Text UI 2. Render Text UI to S T D O U T 3. Receive S T D I N Events 4. Replay Events on D O M 5. G O T O 1 52

Slide 53

Slide 53 text

Conclusion: Back to Text UI 1. Text UI toolchain is not limited 2. H T M L+ C S S+ J S= T U I 3. Declarative Text UI with React! 4. It's easy to extend React unsing injections 53

Slide 54

Slide 54 text

Questions?

Slide 55

Slide 55 text

See more on GitHub

Slide 56

Slide 56 text

g o o . g l / E h w p a 2