1
1
import "./index.css" ;
2
2
3
- import type { Editor } from "codemirror" ;
4
- import type { Ruby } from "./createRuby" ;
5
- import initialSource from "./initialSource" ;
3
+ Promise . all ( [
4
+ // We're going to load the editor asynchronously so that we can get to
5
+ // first-paint faster. This works out nicely since we can use a textarea until
6
+ // this chunk is loaded.
7
+ import ( "./CodeMirror" ) . then ( ( { default : CodeMirror } ) => {
8
+ const editor = document . getElementById ( "editor" ) as HTMLTextAreaElement ;
9
+ const newEditor = document . createElement ( "div" ) ;
10
+ editor . replaceWith ( newEditor ) ;
11
+
12
+ return CodeMirror ( newEditor , {
13
+ lineNumbers : true ,
14
+ mode : "ruby" ,
15
+ theme : "xq-light" ,
16
+ value : editor . value
17
+ } ) ;
18
+ } ) ,
19
+ // We're going to load the Ruby VM chunk asynchronously because it is pretty
20
+ // dang huge (> 40Mb). In the meantime the textarea that is holding the place
21
+ // of the actual functional one is just going to display "Loading...".
22
+ import ( "./createRuby" ) . then ( ( { default : createRuby } ) => createRuby ( ) )
23
+ ] ) . then ( ( [ editor , ruby ] ) => {
24
+ // First, grab a reference to the tree element so that we can update it. Then,
25
+ // set it initially to the tree represented by the source already there.
26
+ const tree = document . getElementById ( "tree" ) as HTMLTextAreaElement ;
27
+ tree . value = ruby . prettyPrint ( editor . getDoc ( ) . getValue ( ) ) ;
28
+ tree . disabled = false ;
6
29
7
- let editorElement = document . getElementById ( "editor" ) as HTMLTextAreaElement ;
8
- const formatElement = document . getElementById ( "format" ) ;
9
- const treeElement = document . getElementById ( "tree" ) as HTMLTextAreaElement ;
10
-
11
- // First, set the initial value of the editor element. It's just going to be a
12
- // textarea until we've loaded the editor chunk.
13
- editorElement . value = initialSource ;
14
-
15
- let editor : Editor = null ;
16
- let ruby : Ruby = null ;
17
-
18
- type SourceChangedEvent = {
19
- source : string
20
- } ; ;
21
-
22
- // This function is called to set up the event handlers once both the editor and
23
- // the ruby chunk have been loaded.
24
- function synchronize ( ) {
25
30
// We're going to handle updates to the source through a custom event. This
26
31
// turns out to be faster than handling the change event directly on the
27
32
// editor since it blocks updates to the UI until the event handled returns.
28
- document . body . addEventListener ( "source-changed" , ( event : CustomEvent < SourceChangedEvent > ) => {
33
+ tree . addEventListener ( "source-changed" , ( event : CustomEvent < { source : string } > ) => {
29
34
try {
30
- treeElement . value = ruby . prettyPrint ( event . detail . source ) ;
35
+ tree . value = ruby . prettyPrint ( event . detail . source ) ;
31
36
} catch ( error ) {
32
37
// For now, just ignoring the error. Eventually I'd like to make this mark
33
38
// an error state on the editor to give feedback to the user.
@@ -37,41 +42,14 @@ function synchronize() {
37
42
// Attach to the editor and dispatch custom source-changed events whenever the
38
43
// value is updated in the editor.
39
44
editor . on ( "change" , ( ) => {
40
- document . body . dispatchEvent ( new CustomEvent < SourceChangedEvent > ( "source-changed" , {
45
+ tree . dispatchEvent ( new CustomEvent < { source : string } > ( "source-changed" , {
41
46
detail : { source : editor . getDoc ( ) . getValue ( ) }
42
47
} ) ) ;
43
48
} ) ;
44
49
45
50
// Attach to the format button to update the source whenever the button is
46
51
// clicked.
47
- formatElement . addEventListener ( "click" , ( ) => {
52
+ document . getElementById ( "format" ) . addEventListener ( "click" , ( ) => {
48
53
editor . getDoc ( ) . setValue ( ruby . format ( editor . getValue ( ) ) ) ;
49
54
} ) ;
50
-
51
- // Finally, un-disable the tree element.
52
- treeElement . disabled = false ;
53
- }
54
-
55
- import ( "./CodeMirror" ) . then ( ( { default : CodeMirror } ) => {
56
- const newEditorElement = document . createElement ( "div" ) ;
57
- editorElement . replaceWith ( newEditorElement ) ;
58
-
59
- editor = CodeMirror ( newEditorElement , {
60
- lineNumbers : true ,
61
- mode : "ruby" ,
62
- theme : "xq-light" ,
63
- value : editorElement . value
64
- } ) ;
65
-
66
- if ( ruby ) {
67
- synchronize ( ) ;
68
- }
69
- } ) ;
70
-
71
- import ( "./createRuby" ) . then ( ( { default : createRuby } ) => createRuby ( ) ) . then ( ( created ) => {
72
- ruby = created ;
73
-
74
- if ( editor ) {
75
- synchronize ( ) ;
76
- }
77
55
} ) ;
0 commit comments