@@ -2,13 +2,6 @@ window.addEventListener("load", function() {
2
2
// If there's no ecmascript 5 support, don't try to initialize
3
3
if ( ! Object . create || ! window . JSON ) return ;
4
4
5
- var sandbox ;
6
- function resetSandbox ( ) {
7
- sandbox = new SandBox ( { loadFiles : window . sandboxLoadFiles } ) ;
8
- window . sandbox = sandbox ;
9
- }
10
- resetSandbox ( ) ;
11
-
12
5
document . body . addEventListener ( "click" , function ( e ) {
13
6
for ( var n = e . target ; n ; n = n . parentNode ) {
14
7
if ( n . className == "c_ident" ) return ;
@@ -45,26 +38,38 @@ window.addEventListener("load", function() {
45
38
"Ctrl-Q" : resetSandbox
46
39
} ;
47
40
41
+ var nextID = 0 ;
42
+
48
43
function activateCode ( node , e , lang ) {
49
44
var code = node . textContent ;
50
45
node . style . display = "none" ;
51
46
var wrap = node . parentNode . insertBefore ( elt ( "div" , { "class" : "editor-wrap" } ) , node ) ;
52
- var editor = CodeMirror ( wrap , {
47
+ var editor = CodeMirror ( function ( div ) { wrap . insertBefore ( div , wrap . firstChild ) } , {
53
48
value : code ,
54
49
mode : lang ,
55
50
extraKeys : keyMap ,
56
51
matchBrackets : true ,
57
52
lineNumbers : true
58
53
} ) ;
59
- editor . on ( "change" , SandBox . Output . repositionFrame ) ;
60
- wrap . style . margin = "0 -5em" ;
61
- setTimeout ( function ( ) { editor . refresh ( ) ; SandBox . Output . repositionFrame ( ) ; } , 600 ) ;
62
- editor . setCursor ( editor . coordsChar ( { left : e . clientX , top : e . clientY } , "client" ) ) ;
63
- editor . focus ( ) ;
54
+ wrap . style . margin = "1rem -5em" ;
55
+ setTimeout ( function ( ) { editor . refresh ( ) ; } , 600 ) ;
56
+ if ( e ) {
57
+ editor . setCursor ( editor . coordsChar ( { left : e . clientX , top : e . clientY } , "client" ) ) ;
58
+ editor . focus ( ) ;
59
+ }
64
60
var out = wrap . appendChild ( elt ( "div" , { "class" : "sandbox-output" } ) ) ;
65
61
var menu = wrap . appendChild ( elt ( "div" , { "class" : "sandbox-menu" , title : "Sandbox menu..." } ) ) ;
62
+ var sandbox = node . getAttribute ( "data-sandbox" ) ;
63
+ if ( lang == "text/html" && ! sandbox ) {
64
+ sandbox = "html" + nextID ++ ;
65
+ node . setAttribute ( "data-sandbox" , sandbox ) ;
66
+ }
66
67
67
- var data = editor . state . context = { editor : editor , wrap : wrap , orig : node , isHTML : lang == "text/html" } ;
68
+ var data = editor . state . context = { editor : editor ,
69
+ wrap : wrap ,
70
+ orig : node ,
71
+ isHTML : lang == "text/html" ,
72
+ sandbox : sandbox } ;
68
73
data . output = new SandBox . Output ( out ) ;
69
74
menu . addEventListener ( "click" , function ( ) { openMenu ( data , menu ) ; } ) ;
70
75
}
@@ -73,8 +78,9 @@ window.addEventListener("load", function() {
73
78
var menu = elt ( "div" , { "class" : "sandbox-open-menu" } ) ;
74
79
var items = [ [ "Run code (ctrl-enter)" , function ( ) { runCode ( data ) ; } ] ,
75
80
[ "Revert to original code" , function ( ) { revertCode ( data ) ; } ] ,
76
- [ "Reset sandbox (ctrl-q)" , resetSandbox ] ,
77
- [ "Deactivate editor (ctrl-d)" , function ( ) { closeCode ( data ) ; } ] ] ;
81
+ [ "Reset sandbox (ctrl-q)" , resetSandbox ] ] ;
82
+ if ( ! data . isHTML || ! data . sandbox )
83
+ items . push ( [ "Deactivate editor (ctrl-d)" , function ( ) { closeCode ( data ) ; } ] ) ;
78
84
items . forEach ( function ( choice ) {
79
85
menu . appendChild ( elt ( "div" , choice [ 0 ] ) ) ;
80
86
} ) ;
@@ -96,20 +102,59 @@ window.addEventListener("load", function() {
96
102
97
103
function runCode ( data ) {
98
104
data . output . clear ( ) ;
99
- var val = data . editor . getValue ( ) ;
105
+ var val = data . editor . getValue ( ) , box = getSandbox ( data . sandbox , data . bisHTML ) ;
100
106
if ( data . isHTML )
101
- sandbox . show ( val , data . output ) ;
107
+ box . setHTML ( val , data . output ) ;
102
108
else
103
- sandbox . run ( val , data . output ) ;
109
+ box . run ( val , data . output ) ;
104
110
}
105
111
106
112
function closeCode ( data ) {
113
+ if ( data . isHTML && data . sandbox ) return ;
107
114
data . wrap . parentNode . removeChild ( data . wrap ) ;
108
115
data . orig . style . display = "" ;
109
- SandBox . Output . repositionFrame ( ) ;
110
116
}
111
117
112
118
function revertCode ( data ) {
113
119
data . editor . setValue ( data . orig . textContent ) ;
114
120
}
121
+
122
+ var sandboxes = { } ;
123
+ function getSandbox ( name , forHTML ) {
124
+ name = name || "null" ;
125
+ if ( sandboxes . hasOwnProperty ( name ) ) return sandboxes [ name ] ;
126
+ var options = { loadFiles : window . sandboxLoadFiles } , html ;
127
+ if ( name != "null" ) {
128
+ var snippets = document . getElementsByClassName ( "snippet" ) ;
129
+ for ( var i = 0 ; i < snippets . length ; i ++ ) {
130
+ var snippet = snippets [ i ] ;
131
+ if ( snippet . getAttribute ( "data-language" ) == "text/html" &&
132
+ snippet . getAttribute ( "data-sandbox" ) == name ) {
133
+ options . place = function ( node ) { placeFrame ( node , snippet ) ; } ;
134
+ if ( ! forHTML ) html = snippet . textContent ;
135
+ break ;
136
+ }
137
+ }
138
+ }
139
+ var box = sandboxes [ name ] = new SandBox ( options ) ;
140
+ if ( html != null ) box . win . document . documentElement . innerHTML = html ;
141
+ return box ;
142
+ }
143
+
144
+ function resetSandbox ( name ) {
145
+ name = name || "null" ;
146
+ if ( ! sandboxes . hasOwnProperty ( name ) ) return ;
147
+ var frame = sandboxes [ name ] . frame ;
148
+ frame . parentNode . removeChild ( frame ) ;
149
+ delete sandboxes [ name ] ;
150
+ }
151
+
152
+ function placeFrame ( frame , snippet ) {
153
+ var wrap = snippet . previousSibling ;
154
+ if ( ! wrap || wrap . className != "editor-wrap" ) {
155
+ activateCode ( snippet , null , "text/html" ) ;
156
+ wrap = snippet . previousSibling ;
157
+ }
158
+ wrap . insertBefore ( frame , wrap . childNodes [ 1 ] ) ;
159
+ }
115
160
} ) ;
0 commit comments