on master help sign in
Merge pull request #5 from fitzgen/initial-sanity-tests
8f8add6Nick Fitzgerald
Cargo.lock+50−64
@@ -40,7 +40,6 @@ dependencies = [
40[[package]]
40[[package]]
41name = "bumpalo"
41name = "bumpalo"
42version = "1.1.0"
42version = "1.1.0"
43−source = "registry+https://github.com/rust-lang/crates.io-index"
44
43
45[[package]]
44[[package]]
46name = "cc"
45name = "cc"
@@ -55,57 +54,67 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
55[[package]]
54[[package]]
56name = "console_error_panic_hook"
55name = "console_error_panic_hook"
57version = "0.1.5"
56version = "0.1.5"
58−source = "registry+https://github.com/rust-lang/crates.io-index"
59dependencies = [
57dependencies = [
60 "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
58 "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
59+ "wasm-bindgen 0.2.31",
60+]
61+
62+[[package]]
63+name = "console_log"
64+version = "0.1.2"
65+source = "registry+https://github.com/rust-lang/crates.io-index"
66+dependencies = [
61− "wasm-bindgen 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
67+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
68+ "web-sys 0.3.8",
62]
69]
63
70
64[[package]]
71[[package]]
65name = "dodrio"
72name = "dodrio"
66version = "0.1.0"
73version = "0.1.0"
67dependencies = [
74dependencies = [
75+ "bumpalo 1.1.0",
68− "bumpalo 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
76+ "console_log 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
77+ "js-sys 0.3.8",
69− "js-sys 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
78+ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
70− "wasm-bindgen 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
79+ "wasm-bindgen 0.2.31",
71− "wasm-bindgen-test 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
80+ "wasm-bindgen-test 0.2.31",
72− "web-sys 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
81+ "web-sys 0.3.8",
73]
82]
74
83
75[[package]]
84[[package]]
76name = "dodrio-counter"
85name = "dodrio-counter"
77version = "0.1.0"
86version = "0.1.0"
78dependencies = [
87dependencies = [
79− "bumpalo 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
88+ "bumpalo 1.1.0",
80− "console_error_panic_hook 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
89+ "console_error_panic_hook 0.1.5",
81 "dodrio 0.1.0",
90 "dodrio 0.1.0",
82− "wasm-bindgen 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
91+ "wasm-bindgen 0.2.31",
83− "wasm-bindgen-test 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
92+ "wasm-bindgen-test 0.2.31",
84− "web-sys 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
93+ "web-sys 0.3.8",
85]
94]
86
95
87[[package]]
96[[package]]
88name = "dodrio-hello-world"
97name = "dodrio-hello-world"
89version = "0.1.0"
98version = "0.1.0"
90dependencies = [
99dependencies = [
91− "bumpalo 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
100+ "bumpalo 1.1.0",
92− "console_error_panic_hook 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
101+ "console_error_panic_hook 0.1.5",
93 "dodrio 0.1.0",
102 "dodrio 0.1.0",
94− "wasm-bindgen 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
103+ "wasm-bindgen 0.2.31",
95− "wasm-bindgen-test 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
104+ "wasm-bindgen-test 0.2.31",
96− "web-sys 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
105+ "web-sys 0.3.8",
97]
106]
98
107
99[[package]]
108[[package]]
100name = "dodrio-input-form"
109name = "dodrio-input-form"
101version = "0.1.0"
110version = "0.1.0"
102dependencies = [
111dependencies = [
103− "bumpalo 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
112+ "bumpalo 1.1.0",
104− "console_error_panic_hook 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
113+ "console_error_panic_hook 0.1.5",
105 "dodrio 0.1.0",
114 "dodrio 0.1.0",
106− "wasm-bindgen 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
115+ "wasm-bindgen 0.2.31",
107− "wasm-bindgen-test 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
116+ "wasm-bindgen-test 0.2.31",
108− "web-sys 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
117+ "web-sys 0.3.8",
109]
118]
110
119
111[[package]]
120[[package]]
@@ -164,9 +173,8 @@ dependencies = [
164[[package]]
173[[package]]
165name = "js-sys"
174name = "js-sys"
166version = "0.3.8"
175version = "0.3.8"
167−source = "registry+https://github.com/rust-lang/crates.io-index"
168dependencies = [
176dependencies = [
169− "wasm-bindgen 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
177+ "wasm-bindgen 0.2.31",
170]
178]
171
179
172[[package]]
180[[package]]
@@ -349,78 +357,70 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
349[[package]]
357[[package]]
350name = "wasm-bindgen"
358name = "wasm-bindgen"
351version = "0.2.31"
359version = "0.2.31"
352−source = "registry+https://github.com/rust-lang/crates.io-index"
353dependencies = [
360dependencies = [
354− "wasm-bindgen-macro 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
361+ "wasm-bindgen-macro 0.2.31",
355]
362]
356
363
357[[package]]
364[[package]]
358name = "wasm-bindgen-backend"
365name = "wasm-bindgen-backend"
359version = "0.2.31"
366version = "0.2.31"
360−source = "registry+https://github.com/rust-lang/crates.io-index"
361dependencies = [
367dependencies = [
362 "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
368 "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
363 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
369 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
364 "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
370 "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
365 "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
371 "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
366 "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
372 "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
367− "wasm-bindgen-shared 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
373+ "wasm-bindgen-shared 0.2.31",
368]
374]
369
375
370[[package]]
376[[package]]
371name = "wasm-bindgen-futures"
377name = "wasm-bindgen-futures"
372version = "0.3.8"
378version = "0.3.8"
373−source = "registry+https://github.com/rust-lang/crates.io-index"
374dependencies = [
379dependencies = [
375 "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
380 "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
376− "js-sys 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
381+ "js-sys 0.3.8",
377− "wasm-bindgen 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
382+ "wasm-bindgen 0.2.31",
378]
383]
379
384
380[[package]]
385[[package]]
381name = "wasm-bindgen-macro"
386name = "wasm-bindgen-macro"
382version = "0.2.31"
387version = "0.2.31"
383−source = "registry+https://github.com/rust-lang/crates.io-index"
384dependencies = [
388dependencies = [
385 "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
389 "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
386− "wasm-bindgen-macro-support 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
390+ "wasm-bindgen-macro-support 0.2.31",
387]
391]
388
392
389[[package]]
393[[package]]
390name = "wasm-bindgen-macro-support"
394name = "wasm-bindgen-macro-support"
391version = "0.2.31"
395version = "0.2.31"
392−source = "registry+https://github.com/rust-lang/crates.io-index"
393dependencies = [
396dependencies = [
394 "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
397 "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
395 "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
398 "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
396 "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
399 "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
397− "wasm-bindgen-backend 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
400+ "wasm-bindgen-backend 0.2.31",
398− "wasm-bindgen-shared 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
401+ "wasm-bindgen-shared 0.2.31",
399]
402]
400
403
401[[package]]
404[[package]]
402name = "wasm-bindgen-shared"
405name = "wasm-bindgen-shared"
403version = "0.2.31"
406version = "0.2.31"
404−source = "registry+https://github.com/rust-lang/crates.io-index"
405
407
406[[package]]
408[[package]]
407name = "wasm-bindgen-test"
409name = "wasm-bindgen-test"
408version = "0.2.31"
410version = "0.2.31"
409−source = "registry+https://github.com/rust-lang/crates.io-index"
410dependencies = [
411dependencies = [
411− "console_error_panic_hook 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
412+ "console_error_panic_hook 0.1.5",
412 "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
413 "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
413− "js-sys 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
414+ "js-sys 0.3.8",
414 "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
415 "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
415− "wasm-bindgen 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
416+ "wasm-bindgen 0.2.31",
416− "wasm-bindgen-futures 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
417+ "wasm-bindgen-futures 0.3.8",
417− "wasm-bindgen-test-macro 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
418+ "wasm-bindgen-test-macro 0.2.31",
418]
419]
419
420
420[[package]]
421[[package]]
421name = "wasm-bindgen-test-macro"
422name = "wasm-bindgen-test-macro"
422version = "0.2.31"
423version = "0.2.31"
423−source = "registry+https://github.com/rust-lang/crates.io-index"
424dependencies = [
424dependencies = [
425 "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
425 "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
426 "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
426 "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -429,7 +429,6 @@ dependencies = [
429[[package]]
429[[package]]
430name = "wasm-bindgen-webidl"
430name = "wasm-bindgen-webidl"
431version = "0.2.25"
431version = "0.2.25"
432−source = "registry+https://github.com/rust-lang/crates.io-index"
433dependencies = [
432dependencies = [
434 "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
433 "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
435 "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
434 "heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -437,21 +436,20 @@ dependencies = [
437 "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
436 "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
438 "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
437 "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
439 "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
438 "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
440− "wasm-bindgen-backend 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
439+ "wasm-bindgen-backend 0.2.31",
441 "weedle 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
440 "weedle 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
442]
441]
443
442
444[[package]]
443[[package]]
445name = "web-sys"
444name = "web-sys"
446version = "0.3.8"
445version = "0.3.8"
447−source = "registry+https://github.com/rust-lang/crates.io-index"
448dependencies = [
446dependencies = [
449 "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
447 "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
450 "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
448 "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
451− "js-sys 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
449+ "js-sys 0.3.8",
452 "sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
450 "sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
453− "wasm-bindgen 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
451+ "wasm-bindgen 0.2.31",
454− "wasm-bindgen-webidl 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)",
452+ "wasm-bindgen-webidl 0.2.25",
455]
453]
456
454
457[[package]]
455[[package]]
@@ -503,17 +501,15 @@ dependencies = [
503"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
501"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
504"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
502"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
505"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0"
503"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0"
506−"checksum bumpalo 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc4fcb5e70b6c60b241977e660f32831396c2a8e2208fdb40277ad22f69e9644"
507"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
504"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
508"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
505"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
509−"checksum console_error_panic_hook 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6c5dd2c094474ec60a6acaf31780af270275e3153bafff2db5995b715295762e"
506+"checksum console_log 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1e7871d2947441b0fdd8e2bd1ce2a2f75304f896582c0d572162d48290683c48"
510"checksum env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afb070faf94c85d17d50ca44f6ad076bce18ae92f0037d350947240a36e9d42e"
507"checksum env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afb070faf94c85d17d50ca44f6ad076bce18ae92f0037d350947240a36e9d42e"
511"checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7"
508"checksum failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6dd377bcc1b1b7ce911967e3ec24fa19c3224394ec05b54aa7b083d498341ac7"
512"checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596"
509"checksum failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "64c2d913fe8ed3b6c6518eedf4538255b989945c14c2a7d5cbff62a5e2120596"
513"checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b"
510"checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b"
514"checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82"
511"checksum heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea04fa3ead4e05e51a7c806fc07271fdbde4e246a6c6d1efd52e72230b771b82"
515"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114"
512"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114"
516−"checksum js-sys 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "27968ddad7df6b0895bf223d475fb71077bbc1de063777ae27cb442163591d36"
517"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
513"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
518"checksum libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)" = "10923947f84a519a45c8fefb7dd1b3e8c08747993381adee176d7a82b4195311"
514"checksum libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)" = "10923947f84a519a45c8fefb7dd1b3e8c08747993381adee176d7a82b4195311"
519"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
515"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
@@ -539,16 +535,6 @@ dependencies = [
539"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
535"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
540"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
536"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
541"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
537"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
542−"checksum wasm-bindgen 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "f45ea87af0efdd3b142836cf2ea233c938fbd0ead3a9da0fd240abd5303d1f5c"
543−"checksum wasm-bindgen-backend 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "65aafeecd4dcb2385505cbd33479c08c961902eae2d19f8cdc09a27c3cd50e09"
544−"checksum wasm-bindgen-futures 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "5b36999d57b7cc8b5463adcef55e9847efce0cb54dc3239a1f8082aae986d841"
545−"checksum wasm-bindgen-macro 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "e3723ce26569facc66e1b53982a1035224d5c0d89a766eb3a45e56153e59b5e1"
546−"checksum wasm-bindgen-macro-support 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "51ff31a6a49abf9743b2cac233bf83a33f24b154878ffdce5a41c8d11f91b3d9"
547−"checksum wasm-bindgen-shared 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "98c697f76b3ab6a0e8abd4489ba81c1ad2eded87f8a871ea5593bb45323400c8"
548−"checksum wasm-bindgen-test 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "371bcf73e0105dd6475ce979641adce782c45685c66502b69014ea3ed33e1c4c"
549−"checksum wasm-bindgen-test-macro 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "14e80d7f52743df9276c7c8a37b793332d746309b0e63696d33d1de3d464c674"
550−"checksum wasm-bindgen-webidl 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "bb97b10781b6df5a71d9c3aa9c8b65023816fdba1b4b13a00eb5591eeeb7f6ea"
551−"checksum web-sys 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "4e4abda3e6221ccb9b9a1853d75c33a37a385e533e784bd8ea121f6ff279ec1c"
552"checksum weedle 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26a4c67f132386d965390b8a734d5d10adbcd30eb5cc74bd9229af8b83f10044"
538"checksum weedle 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26a4c67f132386d965390b8a734d5d10adbcd30eb5cc74bd9229af8b83f10044"
553"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
539"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
554"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
540"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
Cargo.toml+18
@@ -11,6 +11,7 @@ default = []
11bumpalo = "1.0.2"
11bumpalo = "1.0.2"
12wasm-bindgen = "0.2.25"
12wasm-bindgen = "0.2.25"
13js-sys = "0.3.2"
13js-sys = "0.3.2"
14+log = "0.4.6"
14
15
15[dependencies.web-sys]
16[dependencies.web-sys]
16version = "0.3.8"
17version = "0.3.8"
@@ -24,6 +25,15 @@ features = [
24
25
25[dev-dependencies]
26[dev-dependencies]
26wasm-bindgen-test = "0.2"
27wasm-bindgen-test = "0.2"
28+console_log = "0.1.2"
29+
30+[dev-dependencies.web-sys]
31+version = "0.3.8"
32+features = [
33+ "Attr",
34+ "NamedNodeMap",
35+ "NodeList",
36+]
27
37
28[profile.release]
38[profile.release]
29# Tell `rustc` to optimize for small code size.
39# Tell `rustc` to optimize for small code size.
@@ -35,3 +45,11 @@ members = [
35 "./examples/hello-world/crate",
45 "./examples/hello-world/crate",
36 "./examples/input-form/crate",
46 "./examples/input-form/crate",
37]
47]
48+
49+[patch.crates-io]
50+bumpalo = { path = "../bumpalo" }
51+console_error_panic_hook = { path = "../console_error_panic_hook" }
52+wasm-bindgen = { path = "../wasm-bindgen" }
53+wasm-bindgen-test = { path = "../wasm-bindgen/crates/test" }
54+js-sys = { path = "../wasm-bindgen/crates/js-sys" }
55+web-sys = { path = "../wasm-bindgen/crates/web-sys" }
README.md+3−3
@@ -47,10 +47,10 @@ phases. And virtual DOMs are very phase oriented.
47Rendering happens as follows:
47Rendering happens as follows:
48
48
49* The application state is rendered into bump allocation arena (1).
49* The application state is rendered into bump allocation arena (1).
50−* (1) diffed with (2) to produce (3).
50+* (1) diffed with (2) and the changes are emitted into (3).
51−* JavaScript code applies (3) to the physical DOM.
51+* JavaScript code applies the change list in (3) to the physical DOM.
52* (1) and (2) are swapped, double-buffering style, and the new (1) has its bump
52* (1) and (2) are swapped, double-buffering style, and the new (1) has its bump
53− allocation pointer reset.
53+ allocation pointer reset, as does (3).
54* Rinse and repeat.
54* Rinse and repeat.
55
55
56### Change List as Stack Machine
56### Change List as Stack Machine
js/change-list.js+35−33
@@ -12,21 +12,21 @@ function string(mem, pointer, length) {
12const OP_TABLE = [
12const OP_TABLE = [
13 // 0
13 // 0
14 function setText(stack, mem8, mem32, i) {
14 function setText(stack, mem8, mem32, i) {
15− console.log("setText");
15+ // console.log("setText");
16 const pointer = mem32[i++];
16 const pointer = mem32[i++];
17 const length = mem32[i++];
17 const length = mem32[i++];
18 const str = string(mem8, pointer, length);
18 const str = string(mem8, pointer, length);
19− console.log(" str =", str);
19+ // console.log(" str =", str);
20− console.log(" top(stack) =", top(stack));
20+ // console.log(" top(stack) =", top(stack));
21 top(stack).textContent = str;
21 top(stack).textContent = str;
22 return i;
22 return i;
23 },
23 },
24
24
25 // 1
25 // 1
26 function removeSelfAndNextSiblings(stack, mem8, mem32, i) {
26 function removeSelfAndNextSiblings(stack, mem8, mem32, i) {
27− console.log("removeSelfAndNextSiblings");
27+ // console.log("removeSelfAndNextSiblings");
28 const node = stack.pop();
28 const node = stack.pop();
29− console.log(" top(stack) =", node);
29+ // console.log(" top(stack) =", node);
30 let sibling = node.nextSibling;
30 let sibling = node.nextSibling;
31 while (sibling) {
31 while (sibling) {
32 const temp = sibling.nextSibling;
32 const temp = sibling.nextSibling;
@@ -39,11 +39,11 @@ const OP_TABLE = [
39
39
40 // 2
40 // 2
41 function replaceWith(stack, mem8, mem32, i) {
41 function replaceWith(stack, mem8, mem32, i) {
42− console.log("replaceWith");
42+ // console.log("replaceWith");
43 const newNode = stack.pop();
43 const newNode = stack.pop();
44− console.log(" newNode =", newNode);
44+ // console.log(" newNode =", newNode);
45 const oldNode = stack.pop();
45 const oldNode = stack.pop();
46− console.log(" oldNode =", oldNode);
46+ // console.log(" oldNode =", oldNode);
47 oldNode.replaceWith(newNode);
47 oldNode.replaceWith(newNode);
48 stack.push(newNode);
48 stack.push(newNode);
49 return i;
49 return i;
@@ -51,43 +51,43 @@ const OP_TABLE = [
51
51
52 // 3
52 // 3
53 function setAttribute(stack, mem8, mem32, i) {
53 function setAttribute(stack, mem8, mem32, i) {
54− console.log("setAttribute");
54+ // console.log("setAttribute");
55 const pointer1 = mem32[i++];
55 const pointer1 = mem32[i++];
56 const length1 = mem32[i++];
56 const length1 = mem32[i++];
57 const name = string(mem8, pointer1, length1);
57 const name = string(mem8, pointer1, length1);
58− console.log(" name =", name);
58+ // console.log(" name =", name);
59 const pointer2 = mem32[i++];
59 const pointer2 = mem32[i++];
60 const length2 = mem32[i++];
60 const length2 = mem32[i++];
61 const value = string(mem8, pointer2, length2);
61 const value = string(mem8, pointer2, length2);
62− console.log(" value =", value);
62+ // console.log(" value =", value);
63− console.log(" top(stack) =", top(stack));
63+ // console.log(" top(stack) =", top(stack));
64 top(stack).setAttribute(name, value);
64 top(stack).setAttribute(name, value);
65 return i;
65 return i;
66 },
66 },
67
67
68 // 4
68 // 4
69 function removeAttribute(stack, mem8, mem32, i) {
69 function removeAttribute(stack, mem8, mem32, i) {
70− console.log("removeAttribute");
70+ // console.log("removeAttribute");
71 const pointer = mem32[i++];
71 const pointer = mem32[i++];
72 const length = mem32[i++];
72 const length = mem32[i++];
73 const name = string(mem8, pointer, length);
73 const name = string(mem8, pointer, length);
74− console.log(" name =", name);
74+ // console.log(" name =", name);
75 top(stack).removeAttribute(name);
75 top(stack).removeAttribute(name);
76 return i;
76 return i;
77 },
77 },
78
78
79 // 5
79 // 5
80 function pushFirstChild(stack, mem8, mem32, i) {
80 function pushFirstChild(stack, mem8, mem32, i) {
81− console.log("pushFirstChild");
81+ // console.log("pushFirstChild");
82− console.log(" top(stack) =", top(stack));
82+ // console.log(" top(stack) =", top(stack));
83 stack.push(top(stack).firstChild);
83 stack.push(top(stack).firstChild);
84 return i;
84 return i;
85 },
85 },
86
86
87 // 6
87 // 6
88 function popPushNextSibling(stack, mem8, mem32, i) {
88 function popPushNextSibling(stack, mem8, mem32, i) {
89− console.log("popPushNextSibling");
89+ // console.log("popPushNextSibling");
90− console.log(" top(stack) =", top(stack));
90+ // console.log(" top(stack) =", top(stack));
91 const node = stack.pop();
91 const node = stack.pop();
92 stack.push(node.nextSibling);
92 stack.push(node.nextSibling);
93 return i;
93 return i;
@@ -95,16 +95,16 @@ const OP_TABLE = [
95
95
96 // 7
96 // 7
97 function pop(stack, mem8, mem32, i) {
97 function pop(stack, mem8, mem32, i) {
98− console.log("pop");
98+ // console.log("pop");
99− console.log(" top(stack) =", top(stack));
99+ // console.log(" top(stack) =", top(stack));
100 stack.pop();
100 stack.pop();
101 return i;
101 return i;
102 },
102 },
103
103
104 // 8
104 // 8
105 function appendChild(stack, mem8, mem32, i) {
105 function appendChild(stack, mem8, mem32, i) {
106− console.log("appendChild");
106+ // console.log("appendChild");
107− console.log(" top(stack) =", top(stack));
107+ // console.log(" top(stack) =", top(stack));
108 const child = stack.pop();
108 const child = stack.pop();
109 top(stack).appendChild(child);
109 top(stack).appendChild(child);
110 return i;
110 return i;
@@ -112,30 +112,31 @@ const OP_TABLE = [
112
112
113 // 9
113 // 9
114 function createTextNode(stack, mem8, mem32, i) {
114 function createTextNode(stack, mem8, mem32, i) {
115− console.log("appendChild");
115+ // console.log("appendChild");
116 const pointer = mem32[i++];
116 const pointer = mem32[i++];
117 const length = mem32[i++];
117 const length = mem32[i++];
118 const text = string(mem8, pointer, length);
118 const text = string(mem8, pointer, length);
119− console.log(" text =", text);
119+ // console.log(" text =", text);
120− console.log(" top(stack) =", top(stack));
120+ // console.log(" top(stack) =", top(stack));
121 stack.push(document.createTextNode(text));
121 stack.push(document.createTextNode(text));
122 return i;
122 return i;
123 },
123 },
124
124
125 // 10
125 // 10
126 function createElement(stack, mem8, mem32, i) {
126 function createElement(stack, mem8, mem32, i) {
127− console.log("createElement");
127+ // console.log("createElement");
128 const pointer = mem32[i++];
128 const pointer = mem32[i++];
129 const length = mem32[i++];
129 const length = mem32[i++];
130 const tagName = string(mem8, pointer, length);
130 const tagName = string(mem8, pointer, length);
131− console.log(" tagName =", tagName);
131+ // console.log(" tagName =", tagName);
132− console.log(" top(stack) =", top(stack));
132+ // console.log(" top(stack) =", top(stack));
133 stack.push(document.createElement(tagName));
133 stack.push(document.createElement(tagName));
134 return i;
134 return i;
135 }
135 }
136];
136];
137
137
138+// export
138−export class ChangeList {
139+class ChangeList {
139 constructor(container) {
140 constructor(container) {
140 this.container = container;
141 this.container = container;
141 this.ranges = [];
142 this.ranges = [];
@@ -148,7 +149,7 @@ export class ChangeList {
148 }
149 }
149
150
150 applyChanges(memory) {
151 applyChanges(memory) {
151− console.log("======== ChangeList.prototype.applyChanges ==============================");
152+ // console.log("======== ChangeList.prototype.applyChanges ==============================");
152 if (this.ranges.length == 0) {
153 if (this.ranges.length == 0) {
153 return;
154 return;
154 }
155 }
@@ -171,10 +172,11 @@ export class ChangeList {
171 const end = (start + len) / 4;
172 const end = (start + len) / 4;
172 for (let i = start / 4; i < end; ) {
173 for (let i = start / 4; i < end; ) {
173 const op = mem32[i++];
174 const op = mem32[i++];
174− console.log();
175+ // console.log();
175− console.log(OP_TABLE[op].name);
176+ // console.log(OP_TABLE[op].name);
176− console.log(this.stack);
177+ // console.log(this.stack);
177 i = OP_TABLE[op](this.stack, mem8, mem32, i);
178 i = OP_TABLE[op](this.stack, mem8, mem32, i);
178 }
179 }
179 }
180 }
180}
181}
182+window.ChangeList = ChangeList;
src/change_list.rs+16−3
@@ -1,10 +1,12 @@
1use bumpalo::{Bump, BumpAllocSafe};
1use bumpalo::{Bump, BumpAllocSafe};
2+use log::*;
3+use std::sync::Once;
2use wasm_bindgen::prelude::*;
4use wasm_bindgen::prelude::*;
3
5
4pub mod js {
6pub mod js {
5 use wasm_bindgen::prelude::*;
7 use wasm_bindgen::prelude::*;
6
8
7− #[wasm_bindgen(module = "dodrio/change-list")]
9+ #[wasm_bindgen]
8 extern "C" {
10 extern "C" {
9 #[derive(Clone, Debug)]
11 #[derive(Clone, Debug)]
10 pub type ChangeList;
12 pub type ChangeList;
@@ -12,10 +14,10 @@ pub mod js {
12 #[wasm_bindgen(constructor)]
14 #[wasm_bindgen(constructor)]
13 pub fn new(container: &web_sys::Node) -> ChangeList;
15 pub fn new(container: &web_sys::Node) -> ChangeList;
14
16
15− #[wasm_bindgen(method, js_name = addChangeListRange)]
17+ #[wasm_bindgen(structural, method, js_name = addChangeListRange)]
16 pub fn add_change_list_range(this: &ChangeList, start: usize, len: usize);
18 pub fn add_change_list_range(this: &ChangeList, start: usize, len: usize);
17
19
18− #[wasm_bindgen(method, js_name = applyChanges)]
20+ #[wasm_bindgen(structural, method, js_name = applyChanges)]
19 pub fn apply_changes(this: &ChangeList, memory: JsValue);
21 pub fn apply_changes(this: &ChangeList, memory: JsValue);
20 }
22 }
21}
23}
@@ -27,6 +29,17 @@ pub(crate) struct ChangeList {
27
29
28impl ChangeList {
30impl ChangeList {
29 pub(crate) fn new(container: &web_sys::Node) -> ChangeList {
31 pub(crate) fn new(container: &web_sys::Node) -> ChangeList {
32+ // XXX: Because wasm-bindgen-test doesn't support third party JS
33+ // dependencies, we can't use `wasm_bindgen(module = "...")` for our
34+ // `ChangeList` JS import. Instead, this *should* be a local JS snippet,
35+ // but that isn't implemented yet:
36+ // https://github.com/rustwasm/rfcs/pull/6
37+ static EVAL: Once = Once::new();
38+ EVAL.call_once(|| {
39+ js_sys::eval(include_str!("../js/change-list.js"))
40+ .expect("should eval change-list.js OK");
41+ });
42+
30 let bump = Bump::new();
43 let bump = Bump::new();
31 let js = js::ChangeList::new(container);
44 let js = js::ChangeList::new(container);
32 ChangeList { bump, js }
45 ChangeList { bump, js }
src/lib.rs+2−5
@@ -1,17 +1,14 @@
1use bumpalo::Bump;
1use bumpalo::Bump;
2
2
3−#[macro_use]
4−mod macros;
5−
6pub mod change_list;
3pub mod change_list;
7pub mod node;
4pub mod node;
8pub mod vdom;
5pub mod vdom;
9
6
10−pub use self::node::{Attribute, Node, NodeRef};
7+pub use self::node::{Attribute, ElementNode, Node, TextNode};
11pub use self::vdom::Vdom;
8pub use self::vdom::Vdom;
12
9
13pub trait Render {
10pub trait Render {
14− fn render<'a, 'bump>(&'a self, bump: &'bump Bump) -> NodeRef<'bump>
11+ fn render<'a, 'bump>(&'a self, bump: &'bump Bump) -> Node<'bump>
15 where
12 where
16 'a: 'bump;
13 'a: 'bump;
17}
14}
src/macros.rsdeleted−7
@@ -1,7 +0,0 @@
1−macro_rules! debug {
2− ( $fmt:expr $(, $x:expr )* $(,)* ) => {{
3− if cfg!(debug_assertions) {
4− web_sys::console::log_1(&format!($fmt, $($x),*).into());
5− }
6− }}
7−}
src/node.rs+81−64
@@ -1,23 +1,29 @@
1−use bumpalo::BumpAllocSafe;
1+use bumpalo::{Bump, BumpAllocSafe};
2
2
3+/// A node is either a text node or an element.
3−#[derive(Clone, Debug)]
4+#[derive(Debug, Clone)]
4−pub struct Node<'a, Attributes, Children> {
5+pub enum Node<'a> {
5− data: NodeData<'a>,
6+ /// A text node.
6− attributes: Attributes,
7+ Text(TextNode<'a>),
7− children: Children,
8+
9+ /// An element potentially with attributes and children.
10+ Element(ElementNode<'a>),
8}
11}
9
12
13+/// Text nodes are just a string of text. They cannot have attributes or
14+/// children.
10−#[derive(Clone, Copy, Debug)]
15+#[derive(Debug, Clone)]
11−pub enum NodeData<'a> {
16+pub struct TextNode<'a> {
12− Element { tag_name: &'a str },
13− Text { text: &'a str },
17+ pub(crate) text: &'a str,
14}
18}
15
19
20+/// Elements have a tag name, zero or more attributes, and zero or more
21+/// children.
16−#[derive(Clone, Debug)]
22+#[derive(Debug, Clone)]
17−pub struct NodeRef<'a> {
23+pub struct ElementNode<'a> {
18− pub(crate) data: NodeData<'a>,
24+ pub(crate) tag_name: &'a str,
19 pub(crate) attributes: &'a [Attribute<'a>],
25 pub(crate) attributes: &'a [Attribute<'a>],
20− pub(crate) children: &'a [NodeRef<'a>],
26+ pub(crate) children: &'a [Node<'a>],
21}
27}
22
28
23#[derive(Clone, Debug)]
29#[derive(Clone, Debug)]
@@ -26,69 +32,80 @@ pub struct Attribute<'a> {
26 pub value: &'a str,
32 pub value: &'a str,
27}
33}
28
34
29−impl<'a, Attributes, Children> BumpAllocSafe for Node<'a, Attributes, Children>
35+impl<'a> Node<'a> {
30−where
36+ /// Is this node a text node?
31− Attributes: BumpAllocSafe,
37+ pub fn is_text(&self) -> bool {
32− Children: BumpAllocSafe,
38+ match self {
33−{
39+ Node::Text(_) => true,
40+ _ => false,
41+ }
34−}
42+ }
35
43
36−impl<'a, Attributes, Children> From<&'a Node<'a, Attributes, Children>> for NodeRef<'a>
44+ /// Is this node an element?
37−where
45+ pub fn is_element(&self) -> bool {
38− Attributes: AsRef<[Attribute<'a>]>,
46+ match self {
39− Children: AsRef<[NodeRef<'a>]>,
47+ Node::Element { .. } => true,
40−{
48+ _ => false,
41− fn from(node: &'a Node<'a, Attributes, Children>) -> NodeRef<'a> {
42− NodeRef {
43− data: node.data,
44− attributes: node.attributes.as_ref(),
45− children: node.children.as_ref(),
46 }
49 }
47 }
50 }
48}
51}
49
52
50−impl<'a, Attributes, Children> From<&'a mut Node<'a, Attributes, Children>> for NodeRef<'a>
53+impl<'a> TextNode<'a> {
51−where
54+ /// Get this text node's text content.
52− Attributes: AsRef<[Attribute<'a>]>,
55+ pub fn text(&self) -> &'a str {
53− Children: AsRef<[NodeRef<'a>]>,
56+ self.text
54−{
57+ }
55− fn from(node: &'a mut Node<'a, Attributes, Children>) -> NodeRef<'a> {
58+}
56− NodeRef {
59+
57− data: node.data,
60+impl<'a> ElementNode<'a> {
58− attributes: node.attributes.as_ref(),
61+ /// Get this element's tag name.
62+ pub fn tag_name(&self) -> &'a str {
63+ self.tag_name
64+ }
65+
66+ /// Get this element's attributes.
67+ pub fn attributes(&self) -> &'a [Attribute<'a>] {
68+ self.attributes
69+ }
70+
71+ /// Get this element's attributes.
72+ pub fn children(&self) -> &'a [Node<'a>] {
59− children: node.children.as_ref(),
73+ self.children
60− }
61 }
74 }
62}
75}
63
76
64−impl<'a, Attributes, Children> Node<'a, Attributes, Children>
77+impl<'a> BumpAllocSafe for Node<'a> {}
65−where
78+impl<'a> BumpAllocSafe for Attribute<'a> {}
66− Attributes: AsRef<[Attribute<'a>]>,
79+
67− Children: AsRef<[NodeRef<'a>]>,
80+impl<'a> Node<'a> {
68−{
81+ /// Construct a new text node with the given text.
82+ #[inline]
83+ pub fn text(text: &'a str) -> Node<'a> {
84+ Node::Text(TextNode { text })
85+ }
86+
87+ /// Construct a new element node with the given tag name and children.
88+ #[inline]
69− pub fn element(
89+ pub fn element<Attributes, Children>(
90+ bump: &'a Bump,
70 tag_name: &'a str,
91 tag_name: &'a str,
71 attributes: Attributes,
92 attributes: Attributes,
72 children: Children,
93 children: Children,
73− ) -> Node<'a, Attributes, Children> {
94+ ) -> Node<'a>
74− let data = NodeData::Element { tag_name };
95+ where
75− Node {
96+ Attributes: 'a + BumpAllocSafe + AsRef<[Attribute<'a>]>,
76− data,
97+ Children: 'a + BumpAllocSafe + AsRef<[Node<'a>]>,
77− attributes,
98+ {
78− children,
99+ let children: &'a Children = bump.alloc(children);
79− }
100+ let children: &'a [Node<'a>] = children.as_ref();
80− }
101+
81−}
102+ let attributes: &'a Attributes = bump.alloc(attributes);
103+ let attributes: &'a [Attribute<'a>] = attributes.as_ref();
82
104
83−impl<'a> Node<'a, [Attribute<'a>; 0], [NodeRef<'a>; 0]> {
105+ Node::Element(ElementNode {
84− pub fn text(text: &'a str) -> Node<'a, [Attribute<'a>; 0], [NodeRef<'a>; 0]> {
106+ tag_name,
85− let data = NodeData::Text { text };
86− let attributes = [];
87− let children = [];
88− Node {
89− data,
90 attributes,
107 attributes,
91 children,
108 children,
92− }
109+ })
93 }
110 }
94}
111}
src/vdom.rs+37−30
@@ -1,7 +1,8 @@
1use super::change_list::ChangeList;
1use super::change_list::ChangeList;
2−use super::node::{Attribute, Node, NodeData, NodeRef};
2+use super::node::{Attribute, ElementNode, Node, TextNode};
3use super::Render;
3use super::Render;
4use bumpalo::Bump;
4use bumpalo::Bump;
5+use log::*;
5use std::cmp;
6use std::cmp;
6use std::mem;
7use std::mem;
7
8
@@ -11,10 +12,10 @@ pub struct Vdom {
11 container: web_sys::Element,
12 container: web_sys::Element,
12
13
13 // Actually a reference into `self.dom_buffers[0]`.
14 // Actually a reference into `self.dom_buffers[0]`.
14− current_root: Option<NodeRef<'static>>,
15+ current_root: Option<Node<'static>>,
15}
16}
16
17
17−unsafe fn extend_node_lifetime<'a>(node: NodeRef<'a>) -> NodeRef<'static> {
18+unsafe fn extend_node_lifetime<'a>(node: Node<'a>) -> Node<'static> {
18 mem::transmute(node)
19 mem::transmute(node)
19}
20}
20
21
@@ -30,7 +31,7 @@ impl Vdom {
30 container.set_inner_html("");
31 container.set_inner_html("");
31
32
32 // Create a dummy `<div/>` in our container.
33 // Create a dummy `<div/>` in our container.
33− let current_root: NodeRef = dom_buffers[0].alloc(Node::element("div", [], [])).into();
34+ let current_root = Node::element(&dom_buffers[0], "div", [], []);
34 let current_root = Some(unsafe { extend_node_lifetime(current_root) });
35 let current_root = Some(unsafe { extend_node_lifetime(current_root) });
35 let window = web_sys::window().expect("should have acess to the Window");
36 let window = web_sys::window().expect("should have acess to the Window");
36 let document = window
37 let document = window
@@ -85,53 +86,55 @@ impl Vdom {
85 mem::swap(&mut first[0], &mut second[0]);
86 mem::swap(&mut first[0], &mut second[0]);
86 }
87 }
87
88
88− unsafe fn set_current_root(&mut self, current: NodeRef<'static>) {
89+ unsafe fn set_current_root(&mut self, current: Node<'static>) {
89 debug_assert!(self.current_root.is_none());
90 debug_assert!(self.current_root.is_none());
90 self.current_root = Some(current);
91 self.current_root = Some(current);
91 }
92 }
92
93
93− fn diff(&self, old: NodeRef, new: NodeRef) {
94+ fn diff(&self, old: Node, new: Node) {
94− debug!("---------------------------------------------------------");
95+ // debug!("---------------------------------------------------------");
95− debug!("dodrio::Vdom::diff");
96+ // debug!("dodrio::Vdom::diff");
96− debug!(" old = {:#?}", old);
97+ // debug!(" old = {:#?}", old);
97− debug!(" new = {:#?}", new);
98+ // debug!(" new = {:#?}", new);
98− match (new.data, old.data) {
99+ match (&new, old) {
99− (NodeData::Text { text: new_text }, NodeData::Text { text: old_text }) => {
100+ (&Node::Text(TextNode { text: new_text }), Node::Text(TextNode { text: old_text })) => {
100 debug!(" both are text nodes");
101 debug!(" both are text nodes");
101 if new_text != old_text {
102 if new_text != old_text {
102 debug!(" text needs updating");
103 debug!(" text needs updating");
103 self.change_list.emit_set_text(new_text);
104 self.change_list.emit_set_text(new_text);
104 }
105 }
105 }
106 }
106− (NodeData::Text { .. }, NodeData::Element { .. }) => {
107+ (&Node::Text(TextNode { .. }), Node::Element(ElementNode { .. })) => {
107 debug!(" replacing a text node with an element");
108 debug!(" replacing a text node with an element");
108 self.create(new);
109 self.create(new);
109 self.change_list.emit_replace_with();
110 self.change_list.emit_replace_with();
110 }
111 }
111− (NodeData::Element { .. }, NodeData::Text { .. }) => {
112+ (&Node::Element(ElementNode { .. }), Node::Text(TextNode { .. })) => {
112 debug!(" replacing an element with a text node");
113 debug!(" replacing an element with a text node");
113 self.create(new);
114 self.create(new);
114 self.change_list.emit_replace_with();
115 self.change_list.emit_replace_with();
115 }
116 }
116 (
117 (
117− NodeData::Element {
118+ &Node::Element(ElementNode {
118 tag_name: new_tag_name,
119 tag_name: new_tag_name,
120+ attributes: new_attributes,
121+ children: new_children,
119− },
122+ }),
120− NodeData::Element {
123+ Node::Element(ElementNode {
121 tag_name: old_tag_name,
124 tag_name: old_tag_name,
125+ attributes: old_attributes,
126+ children: old_children,
122− },
127+ }),
123 ) => {
128 ) => {
124 debug!(" updating an element");
129 debug!(" updating an element");
125−
126 if new_tag_name != old_tag_name {
130 if new_tag_name != old_tag_name {
127 debug!(" different tag names; creating new element and replacing old element");
131 debug!(" different tag names; creating new element and replacing old element");
128 self.create(new);
132 self.create(new);
129 self.change_list.emit_replace_with();
133 self.change_list.emit_replace_with();
130 return;
134 return;
131 }
135 }
132−
133− self.diff_attributes(old.attributes, new.attributes);
136+ self.diff_attributes(old_attributes, new_attributes);
134− self.diff_children(old.children, new.children);
137+ self.diff_children(old_children, new_children);
135 }
138 }
136 }
139 }
137 }
140 }
@@ -165,7 +168,7 @@ impl Vdom {
165 }
168 }
166 }
169 }
167
170
168− fn diff_children(&self, old: &[NodeRef], new: &[NodeRef]) {
171+ fn diff_children(&self, old: &[Node], new: &[Node]) {
169 debug!(" updating children shared by old and new");
172 debug!(" updating children shared by old and new");
170
173
171 let num_children_to_diff = cmp::min(new.len(), old.len());
174 let num_children_to_diff = cmp::min(new.len(), old.len());
@@ -217,18 +220,22 @@ impl Vdom {
217 }
220 }
218 }
221 }
219
222
220− fn create(&self, node: NodeRef) {
223+ fn create(&self, node: Node) {
221− debug!("dodrio::Vdom::create({:#?})", node);
224+ // debug!("dodrio::Vdom::create({:#?})", node);
222− match node.data {
225+ match node {
223− NodeData::Text { text } => {
226+ Node::Text(TextNode { text }) => {
224 self.change_list.emit_create_text_node(text);
227 self.change_list.emit_create_text_node(text);
225 }
228 }
229+ Node::Element(ElementNode {
226− NodeData::Element { tag_name } => {
230+ tag_name,
231+ attributes,
232+ children,
233+ }) => {
227 self.change_list.emit_create_element(tag_name);
234 self.change_list.emit_create_element(tag_name);
228− for attr in node.attributes {
235+ for attr in attributes {
229 self.change_list.emit_set_attribute(&attr.name, &attr.value);
236 self.change_list.emit_set_attribute(&attr.name, &attr.value);
230 }
237 }
231− for child in node.children {
238+ for child in children {
232 self.create(child.clone());
239 self.create(child.clone());
233 self.change_list.emit_append_child();
240 self.change_list.emit_append_child();
234 }
241 }
tests/web.rs+135−3
@@ -2,12 +2,144 @@
2
2
3#![cfg(target_arch = "wasm32")]
3#![cfg(target_arch = "wasm32")]
4
4
5−extern crate wasm_bindgen_test;
5+use bumpalo::Bump;
6+use dodrio::{
7+ node::{Attribute, Node},
8+ vdom::Vdom,
9+ Render,
10+};
11+use log::*;
12+use wasm_bindgen::JsCast;
6use wasm_bindgen_test::*;
13use wasm_bindgen_test::*;
7
14
8wasm_bindgen_test_configure!(run_in_browser);
15wasm_bindgen_test_configure!(run_in_browser);
9
16
17+fn window() -> web_sys::Window {
18+ web_sys::window().expect("no global `window` exists")
19+}
20+
21+fn document() -> web_sys::Document {
22+ window()
23+ .document()
24+ .expect("should have a document on window")
25+}
26+
27+fn create_element(tag: &str) -> web_sys::Element {
28+ document()
29+ .create_element(tag)
30+ .expect("should create element OK")
31+}
32+
33+fn init_logging() {
34+ use std::sync::Once;
35+ static START: Once = Once::new();
36+ START.call_once(|| {
37+ console_log::init_with_level(Level::Trace).expect("could not initialize console_log");
38+ });
39+}
40+
41+fn assert_rendered<R: Render>(container: &web_sys::Element, r: &R) {
42+ init_logging();
43+ let bump = &Bump::new();
44+ let node = r.render(bump);
45+ let child = container
46+ .first_child()
47+ .expect("container does not have anything rendered into it?");
48+ check_node(&child, &node);
49+
50+ fn stringify_actual_node(n: &web_sys::Node) -> String {
51+ if let Some(el) = n.dyn_ref::<web_sys::Element>() {
52+ el.outer_html()
53+ } else {
54+ format!("#text({:?})", n.text_content())
55+ }
56+ }
57+
58+ fn check_node(actual: &web_sys::Node, expected: &Node) {
59+ info!("check_render:");
60+ info!(" actual = {}", stringify_actual_node(&actual));
61+ info!(" expected = {:?}", expected);
62+ match expected {
63+ Node::Text(text_node) => {
64+ assert_eq!(actual.node_name().to_uppercase(), "#TEXT");
65+ assert_eq!(actual.text_content().unwrap_or_default(), text_node.text());
66+ }
67+ Node::Element(elem) => {
68+ assert_eq!(
69+ actual.node_name().to_uppercase(),
70+ elem.tag_name().to_uppercase()
71+ );
72+ let actual = actual
73+ .dyn_ref::<web_sys::Element>()
74+ .expect("`actual` should be an `Element`");
75+ check_attributes(actual.attributes(), elem.attributes());
76+ check_children(actual.child_nodes(), elem.children());
77+ }
78+ }
79+ }
80+
81+ fn check_attributes(actual: web_sys::NamedNodeMap, expected: &[Attribute]) {
82+ assert_eq!(actual.length(), expected.len() as u32);
83+ for attr in expected {
84+ let actual_attr = actual
85+ .get_named_item(attr.name)
86+ .expect(&format!("should have attribute \"{}\"", attr.name));
87+ assert_eq!(actual_attr.value(), attr.value);
88+ }
89+ }
90+
91+ fn check_children(actual: web_sys::NodeList, expected: &[Node]) {
92+ assert_eq!(actual.length(), expected.len() as u32);
93+ for (i, child) in expected.iter().enumerate() {
94+ let actual_child = actual.item(i as u32).unwrap();
95+ check_node(&actual_child, child);
96+ }
97+ }
98+}
99+
100+#[wasm_bindgen_test]
101+fn render_initial_text() {
102+ struct Hello;
103+
104+ impl Render for Hello {
105+ fn render<'a, 'bump>(&'a self, _bump: &'bump Bump) -> Node<'bump>
106+ where
107+ 'a: 'bump,
108+ {
109+ Node::text("Hello")
110+ }
111+ }
112+
113+ let container = create_element("div");
114+ Vdom::new(&container, &Hello);
115+ assert_rendered(&container, &Hello);
116+}
117+
10#[wasm_bindgen_test]
118#[wasm_bindgen_test]
11−fn pass() {
119+fn render_initial_node() {
12− assert_eq!(1 + 1, 2);
120+ struct Hello;
121+
122+ impl Render for Hello {
123+ fn render<'a, 'bump>(&'a self, bump: &'bump Bump) -> Node<'bump>
124+ where
125+ 'a: 'bump,
126+ {
127+ Node::element(
128+ bump,
129+ "div",
130+ [Attribute {
131+ name: "id",
132+ value: "hello-world",
133+ }],
134+ [
135+ Node::text("Hello "),
136+ Node::element(bump, "span", [], [Node::text("World!")]),
137+ ],
138+ )
139+ }
140+ }
141+
142+ let container = create_element("div");
143+ Vdom::new(&container, &Hello);
144+ assert_rendered(&container, &Hello);
13}
145}