Skip to content

Commit d82272b

Browse files
Fix #1832: Browser compiler should run code using globally-scoped eval (#5047)
* Explicitly turn off minify mangling, because it was previously implicitly disabled by the existence of the `eval` call we’re about to remove * Update babel-core * Run browser-compiled scripts using window.eval rather than just eval, to use a clean scope (many times faster) * Update output * Fix browser-based test broken by #5028 * Update output
1 parent fe75548 commit d82272b

File tree

10 files changed

+28
-15
lines changed

10 files changed

+28
-15
lines changed

Cakefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ transpile = (code) ->
7272
# Exclude the `modules` plugin in order to not break the `}(this));`
7373
# at the end of the `build:browser` code block.
7474
presets.push ['env', {modules: no}] unless process.env.TRANSFORM is 'false'
75-
presets.push 'minify' unless process.env.MINIFY is 'false'
75+
presets.push ['minify', {mangle: no}] unless process.env.MINIFY is 'false'
7676
babelOptions =
7777
compact: process.env.MINIFY isnt 'false'
7878
presets: presets

docs/v2/browser-compiler/coffeescript.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/v2/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6298,7 +6298,7 @@ <h2 class="header">
62986298

62996299
<script src="browser-compiler/coffeescript.js"></script>
63006300
<script>
6301-
(function(){window.location.origin||(window.location.origin=window.location.protocol+'//'+window.location.hostname),window.GA_TRACKING_ID='UA-106156830-1',null==window.dataLayer&&(window.dataLayer=[]),window.gtag=function(){window.dataLayer.push(arguments)},window.gtag('js',new Date),window.gtag('config',window.GA_TRACKING_ID),$(document).ready(function(){var clearHash,closeTry,editors,initializeEditor,initializeScrollspyFromHash,initializeTryEditors,lastCompilationElapsedTime,previousHash,replaceState,textareas,toggleSidebar,toggleTry;if(toggleSidebar=function(){return $('.navbar-toggler, .sidebar').toggleClass('show')},$('[data-toggle="offcanvas"]').click(toggleSidebar),$('[data-action="sidebar-nav"]').click(function(a){return $('.navbar-toggler').is(':visible')&&(a.preventDefault(),toggleSidebar(),setTimeout(function(){return window.location=a.target.href},260)),gtag('event','sidebar_navigate',{event_category:'navigation',event_label:a.target.href.replace(window.location.origin,'')})}),$('.main').scrollspy({target:'#contents',offset:Math.round($('main').css('padding-top').replace('px',''))}),initializeScrollspyFromHash=function(a){return $('#contents a.active[href!=\''+a+'\']').removeClass('show')},$('.main').on('activate.bs.scrollspy',function(a,b){var c;if($('#contents a.active[href!=\''+b.relatedTarget+'\']').removeClass('show'),c=$('#contents a[href=\''+b.relatedTarget+'\']'),c.prop('href')!==window.location.origin+'/#try')return replaceState(c.prop('href')),gtag('config',GA_TRACKING_ID,{page_path:c.prop('href').replace(window.location.origin,'')})}),textareas=[],editors=[],lastCompilationElapsedTime=200,$('textarea').each(function(a){return textareas[a]=this,$(this).data('index',a)}),initializeEditor=function(a){var b,c,d,e;if(c=a.data('index'),d=a.hasClass('javascript-output')?'javascript':'coffeescript',editors[c]=b=CodeMirror.fromTextArea(a[0],{mode:d,theme:'twilight',indentUnit:2,tabSize:2,lineWrapping:!0,lineNumbers:!1,inputStyle:'contenteditable',readOnly:'coffeescript'!==d,viewportMargin:2e308}),'coffeescript'===d)return e=null,b.on('change',function(){return clearTimeout(e),e=setTimeout(function(){var d,e,f,g,h;f=Date.now();try{if(d=b.getValue(),0===c&&$('#try').hasClass('show')){$('#try').hasClass('show')&&(g='try:'+encodeURIComponent(d),replaceState(window.location.href.split('#')[0]+'#'+g));try{null!=window.localStorage&&window.localStorage.setItem('tryCoffeeScriptCode',d)}catch(a){e=a}}h=CoffeeScript.compile(d,{bare:!0}),lastCompilationElapsedTime=Math.max(200,Date.now()-f)}catch(a){e=a,h=''+e}return editors[c+1].setValue(h),gtag('event','edit_code',{event_category:'engagement',event_label:a.closest('[data-example]').data('example')})},lastCompilationElapsedTime)}),b.addKeyMap({Tab:function Tab(a){return a.somethingSelected()?a.indentSelection('add'):/^\t/m.test(a.getValue())?a.execCommand('insertTab'):a.execCommand('insertSoftTab')},"Shift-Tab":function ShiftTab(a){return a.indentSelection('subtract')},Enter:function Enter(a){return a.options.indentWithTabs=/^\t/m.test(a.getValue()),a.execCommand('newlineAndIndent')}})},$('.placeholder-code').one('mouseover',function(){var a,b;return b=$(this).prev('textarea'),$(this).remove(),initializeEditor(b),a=$(b.parent().siblings()[0]),a.children('.placeholder-code').remove(),initializeEditor($(a.children('textarea')[0]))}),initializeTryEditors=function(){return initializeEditor($('#try-coffeescript-coffee')),initializeEditor($('#try-coffeescript-js'))},$('[data-action="run-code-example"]').click(function(){var index,js,run;return run=$(this).data('run'),index=$('#'+$(this).data('example')+'-js').data('index'),js=null==editors[index]?$(textareas[index]).val():editors[index].getValue(),!0!==run&&(js=js+'\nalert('+unescape(run)+');'),eval(js),gtag('event','run_code',{event_category:'engagement',event_label:$(this).closest('[data-example]').data('example')})}),previousHash=null,toggleTry=function(a){var b,c;if($('#try, #try-link').toggleClass('show'),!$('#try').hasClass('show'))return previousHash?replaceState(previousHash):clearHash();if(window.location.hash&&(previousHash=window.location.hash),0===$('#try .CodeMirror').length&&initializeTryEditors(),a&&null!=window.localStorage)try{return b=window.localStorage.getItem('tryCoffeeScriptCode'),null==b?replaceState('#try'):editors[0].setValue(b)}catch(a){return c=a,replaceState('#try')}else return replaceState('#try')},closeTry=function(){return $('#try, #try-link').removeClass('show'),previousHash?replaceState(previousHash):clearHash()},$('[data-toggle="try"]').click(function(a){return a.preventDefault(),toggleTry(!0)}),$('[data-close="try"]').click(closeTry),$('[data-action="scroll-to-top"]').click(function(){if(!$('#try').hasClass('show'))return $('.main')[0].scrollTop=0,setTimeout(clearHash,10)}),clearHash=function(){return window.history.replaceState({},document.title,window.location.pathname)},replaceState=function(a){return 0===(null==a?void 0:a.indexOf('#'))&&(a=''+window.location.pathname+a),window.history.replaceState({},document.title,a||'')},$(window).on('hashchange',function(){if(''===window.location.hash)return clearHash()}),null!=window.location.hash){if('#try'===window.location.hash)return toggleTry(!0);if(0===window.location.hash.indexOf('#try'))return 0===$('#try .CodeMirror').length&&initializeTryEditors(),editors[0].setValue(decodeURIComponent(window.location.hash.slice(5))),toggleTry(!1);if(''===window.location.hash)return clearHash();if(initializeScrollspyFromHash(window.location.hash),1<window.location.hash.length)return document.getElementById(window.location.hash.slice(1).replace(/try:.*/,'')).scrollIntoView()}})}).call(this);
6301+
(function(){window.location.origin||(window.location.origin=window.location.protocol+'//'+window.location.hostname),window.GA_TRACKING_ID='UA-106156830-1',null==window.dataLayer&&(window.dataLayer=[]),window.gtag=function(){window.dataLayer.push(arguments)},window.gtag('js',new Date),window.gtag('config',window.GA_TRACKING_ID),$(document).ready(function(){var clearHash,closeTry,editors,initializeEditor,initializeScrollspyFromHash,initializeTryEditors,lastCompilationElapsedTime,previousHash,replaceState,textareas,toggleSidebar,toggleTry;if(toggleSidebar=function(){return $('.navbar-toggler, .sidebar').toggleClass('show')},$('[data-toggle="offcanvas"]').click(toggleSidebar),$('[data-action="sidebar-nav"]').click(function(event){return $('.navbar-toggler').is(':visible')&&(event.preventDefault(),toggleSidebar(),setTimeout(function(){return window.location=event.target.href},260)),gtag('event','sidebar_navigate',{event_category:'navigation',event_label:event.target.href.replace(window.location.origin,'')})}),$('.main').scrollspy({target:'#contents',offset:Math.round($('main').css('padding-top').replace('px',''))}),initializeScrollspyFromHash=function(hash){return $('#contents a.active[href!=\''+hash+'\']').removeClass('show')},$('.main').on('activate.bs.scrollspy',function(event,target){var $target;if($('#contents a.active[href!=\''+target.relatedTarget+'\']').removeClass('show'),$target=$('#contents a[href=\''+target.relatedTarget+'\']'),$target.prop('href')!==window.location.origin+'/#try')return replaceState($target.prop('href')),gtag('config',GA_TRACKING_ID,{page_path:$target.prop('href').replace(window.location.origin,'')})}),textareas=[],editors=[],lastCompilationElapsedTime=200,$('textarea').each(function(index){return textareas[index]=this,$(this).data('index',index)}),initializeEditor=function($textarea){var editor,index,mode,pending;if(index=$textarea.data('index'),mode=$textarea.hasClass('javascript-output')?'javascript':'coffeescript',editors[index]=editor=CodeMirror.fromTextArea($textarea[0],{mode:mode,theme:'twilight',indentUnit:2,tabSize:2,lineWrapping:!0,lineNumbers:!1,inputStyle:'contenteditable',readOnly:'coffeescript'!==mode,viewportMargin:2e308}),'coffeescript'===mode)return pending=null,editor.on('change',function(){return clearTimeout(pending),pending=setTimeout(function(){var coffee,exception,lastCompilationStartTime,link,output;lastCompilationStartTime=Date.now();try{if(coffee=editor.getValue(),0===index&&$('#try').hasClass('show')){$('#try').hasClass('show')&&(link='try:'+encodeURIComponent(coffee),replaceState(window.location.href.split('#')[0]+'#'+link));try{null!=window.localStorage&&window.localStorage.setItem('tryCoffeeScriptCode',coffee)}catch(error){exception=error}}output=CoffeeScript.compile(coffee,{bare:!0}),lastCompilationElapsedTime=Math.max(200,Date.now()-lastCompilationStartTime)}catch(error){exception=error,output=''+exception}return editors[index+1].setValue(output),gtag('event','edit_code',{event_category:'engagement',event_label:$textarea.closest('[data-example]').data('example')})},lastCompilationElapsedTime)}),editor.addKeyMap({Tab:function Tab(cm){return cm.somethingSelected()?cm.indentSelection('add'):/^\t/m.test(cm.getValue())?cm.execCommand('insertTab'):cm.execCommand('insertSoftTab')},"Shift-Tab":function ShiftTab(cm){return cm.indentSelection('subtract')},Enter:function Enter(cm){return cm.options.indentWithTabs=/^\t/m.test(cm.getValue()),cm.execCommand('newlineAndIndent')}})},$('.placeholder-code').one('mouseover',function(){var $siblingColumn,$textarea;return $textarea=$(this).prev('textarea'),$(this).remove(),initializeEditor($textarea),$siblingColumn=$($textarea.parent().siblings()[0]),$siblingColumn.children('.placeholder-code').remove(),initializeEditor($($siblingColumn.children('textarea')[0]))}),initializeTryEditors=function(){return initializeEditor($('#try-coffeescript-coffee')),initializeEditor($('#try-coffeescript-js'))},$('[data-action="run-code-example"]').click(function(){var index,js,run;return run=$(this).data('run'),index=$('#'+$(this).data('example')+'-js').data('index'),js=null==editors[index]?$(textareas[index]).val():editors[index].getValue(),!0!==run&&(js=js+'\nalert('+unescape(run)+');'),window.eval(js),gtag('event','run_code',{event_category:'engagement',event_label:$(this).closest('[data-example]').data('example')})}),previousHash=null,toggleTry=function(checkLocalStorage){var coffee,exception;if($('#try, #try-link').toggleClass('show'),!$('#try').hasClass('show'))return previousHash?replaceState(previousHash):clearHash();if(window.location.hash&&(previousHash=window.location.hash),0===$('#try .CodeMirror').length&&initializeTryEditors(),checkLocalStorage&&null!=window.localStorage)try{return coffee=window.localStorage.getItem('tryCoffeeScriptCode'),null==coffee?replaceState('#try'):editors[0].setValue(coffee)}catch(error){return exception=error,replaceState('#try')}else return replaceState('#try')},closeTry=function(){return $('#try, #try-link').removeClass('show'),previousHash?replaceState(previousHash):clearHash()},$('[data-toggle="try"]').click(function(event){return event.preventDefault(),toggleTry(!0)}),$('[data-close="try"]').click(closeTry),$('[data-action="scroll-to-top"]').click(function(){if(!$('#try').hasClass('show'))return $('.main')[0].scrollTop=0,setTimeout(clearHash,10)}),clearHash=function(){return window.history.replaceState({},document.title,window.location.pathname)},replaceState=function(newURL){return 0===(null==newURL?void 0:newURL.indexOf('#'))&&(newURL=''+window.location.pathname+newURL),window.history.replaceState({},document.title,newURL||'')},$(window).on('hashchange',function(){if(''===window.location.hash)return clearHash()}),null!=window.location.hash){if('#try'===window.location.hash)return toggleTry(!0);if(0===window.location.hash.indexOf('#try'))return 0===$('#try .CodeMirror').length&&initializeTryEditors(),editors[0].setValue(decodeURIComponent(window.location.hash.slice(5))),toggleTry(!1);if(''===window.location.hash)return clearHash();if(initializeScrollspyFromHash(window.location.hash),1<window.location.hash.length)return document.getElementById(window.location.hash.slice(1).replace(/try:.*/,'')).scrollIntoView()}})}).call(this);
63026302
</script>
63036303
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-106156830-1"></script>
63046304

docs/v2/test.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ <h1>CoffeeScript Test Suite</h1>
148148
ok yes
149149
else if e.toString().indexOf('[stdin]') is 0 # Handle comparing error messages
150150
ok err e
151+
else if err instanceof RegExp
152+
ok err.test e
151153
else
152154
eq e, err
153155
else

documentation/site/docs.coffee

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ $(document).ready ->
143143
else
144144
$(textareas[index]).val()
145145
js = "#{js}\nalert(#{unescape run});" unless run is yes
146-
eval js
146+
window.eval js
147147
gtag 'event', 'run_code',
148148
event_category: 'engagement'
149149
event_label: $(@).closest('[data-example]').data('example')

documentation/site/test.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ <h1>CoffeeScript Test Suite</h1>
108108
ok yes
109109
else if e.toString().indexOf('[stdin]') is 0 # Handle comparing error messages
110110
ok err e
111+
else if err instanceof RegExp
112+
ok err.test e
111113
else
112114
eq e, err
113115
else

lib/coffeescript/browser.js

Lines changed: 8 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
"url": "git://github.com/jashkenas/coffeescript.git"
4040
},
4141
"devDependencies": {
42-
"babel-core": "~6.26.2",
42+
"babel-core": "~6.26.3",
4343
"babel-preset-babili": "~0.1.4",
4444
"babel-preset-env": "~1.6.1",
4545
"babel-preset-minify": "^0.4.0",

src/browser.coffee

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@
44
# `text/coffeescript` script tags, source maps via data-URLs, and so on.
55

66
CoffeeScript = require './coffeescript'
7-
compile = CoffeeScript.compile
7+
{ compile } = CoffeeScript
88

9-
# Use standard JavaScript `eval` to eval code.
9+
# Use `window.eval` to evaluate code, rather than just `eval`, to run the
10+
# script in a clean global scope rather than inheriting the scope of the
11+
# CoffeeScript compiler. (So that `cake test:browser` also works in Node,
12+
# use either `window.eval` or `global.eval` as appropriate).
1013
CoffeeScript.eval = (code, options = {}) ->
1114
options.bare ?= on
12-
eval compile code, options
15+
globalRoot = if window? then window else global
16+
globalRoot['eval'] compile code, options
1317

1418
# Running code does not provide access to this scope.
1519
CoffeeScript.run = (code, options = {}) ->

0 commit comments

Comments
 (0)