|
109 | 109 |
|
110 | 110 | our $RUN_CODE_IN_IFRAME=0; |
111 | 111 |
|
| 112 | +my $run_code_body = <<'END_CODE'; |
| 113 | + my (@warns,@output); |
| 114 | + #TODO Later: Capture STDOUT too? (and STDERR, instead of $SIG{__WARN__})? |
| 115 | + my $ok = do { |
| 116 | + local $SIG{__WARN__} = sub { push @warns, shift }; |
| 117 | + eval "package RunCode {$code\n};1" }; |
| 118 | + my $err = $ok ? undef : $@||"Unknown error"; |
| 119 | + defined && s/\bat .+? line \d+(?:\.$|,\h)//mg for (@warns,$err); |
| 120 | + chomp(@warns); |
| 121 | + my $rv = { ctx=>$context, warns=>\@warns, $ok ? (out=>\@output) : (err=>$err) }; |
| 122 | +END_CODE |
| 123 | + |
112 | 124 | my $runcode_iframe; |
113 | 125 | my $runcode_message_callback; # assume a single callback for now |
114 | 126 | if ($RUN_CODE_IN_IFRAME) { # https://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/ |
|
130 | 142 | die "Bad arguments" unless ref $data eq 'ARRAY' |
131 | 143 | && @$data==3 && !grep {ref} @$data; |
132 | 144 | my ($context,$code,$input) = @$data; |
133 | | - # --- begin code copied from sub run_code --- |
134 | | - my (@warns,@output); |
135 | | - my $ok = do { |
136 | | - local $SIG{__WARN__} = sub { push @warns, shift }; |
137 | | - eval "package RunCode {$code\n};1" }; |
138 | | - my $err = $ok ? undef : $@||"Unknown error"; |
139 | | - defined && s/\bat .+? line \d+(?:\.$|,\h)//mg for (@warns,$err); |
140 | | - chomp(@warns); |
141 | | - my $rv = { ctx=>$context, warns=>\@warns, $ok ? (out=>\@output) : (err=>$err) }; |
142 | | - # --- end code copied from sub run_code --- |
| 145 | + __RUNCODEBODY__ |
143 | 146 | my $origin = $event->{origin} eq 'null' ? '*' : $event->{origin}; |
144 | 147 | $event->{source}->postMessage($rv, $origin); |
145 | 148 | }, undef); |
|
149 | 152 | </ht__ml> |
150 | 153 | END_IFRAME_HTML |
151 | 154 | $iframe_html=~s#</\w+\K__(?=\w+>)##ig; |
| 155 | + $iframe_html=~s/__RUNCODEBODY__/$run_code_body/; |
152 | 156 | my $iframe_blob_url = js('URL')->createObjectURL( |
153 | 157 | WebPerl::js_new('Blob',[$iframe_html],{type=>"text/html;charset=utf-8"}) ); |
154 | 158 | my $iframe = $jq->('<iframe/>', {id=>'PerlEval_IFrame', sandbox=>'allow-scripts', |
|
331 | 335 | hashchange(); |
332 | 336 | update(); |
333 | 337 |
|
334 | | -sub run_code { |
| 338 | +*run_code = eval( q{ sub { |
335 | 339 | my ($context,$code,$input,$callback) = @_; |
336 | 340 | if ($RUN_CODE_IN_IFRAME) { |
337 | 341 | $runcode_message_callback = $callback; # assume a single callback for now |
338 | 342 | $runcode_iframe->postMessage([$context,$code,$input], '*'); |
339 | 343 | return } |
340 | | - # --- begin code copied to iframe --- |
341 | | - my (@warns,@output); |
342 | | - #TODO Later: Capture STDOUT too? (and STDERR, instead of $SIG{__WARN__})? |
343 | | - my $ok = do { |
344 | | - local $SIG{__WARN__} = sub { push @warns, shift }; |
345 | | - eval "package RunCode {$code\n};1" }; |
346 | | - my $err = $ok ? undef : $@||"Unknown error"; |
347 | | - defined && s/\bat .+? line \d+(?:\.$|,\h)//mg for (@warns,$err); |
348 | | - chomp(@warns); |
349 | | - my $rv = { ctx=>$context, warns=>\@warns, $ok ? (out=>\@output) : (err=>$err) }; |
350 | | - # --- end code copied to iframe --- |
| 344 | + __RUNCODEBODY__ |
351 | 345 | $callback->($rv); |
352 | | -} |
| 346 | +} } =~ s/__RUNCODEBODY__/$run_code_body/r ) || die( $@||"unknown error" ); |
353 | 347 |
|
354 | 348 | sub update { |
355 | 349 | state $timeout_id; |
|
0 commit comments