CoffeeScript = require './coffeescript'
{ compile } = CoffeeScript
这个 **浏览器** 兼容层扩展了核心 CoffeeScript 函数,以便在浏览器中直接编译代码时能够顺利运行。我们添加了对通过 **XHR** 加载远程 Coffee 脚本、text/coffeescript
脚本标签、通过 data-URL 加载源映射等的支持。
CoffeeScript = require './coffeescript'
{ compile } = CoffeeScript
使用 window.eval
来评估代码,而不是仅仅使用 eval
,以便在干净的全局作用域中运行脚本,而不是继承 CoffeeScript 编译器的作用域。(因此 cake test:browser
也能在 Node 中运行,请根据需要使用 window.eval
或 global.eval
)。
CoffeeScript.eval = (code, options = {}) ->
options.bare ?= on
globalRoot = if window? then window else global
globalRoot['eval'] compile code, options
运行代码无法访问此作用域。
CoffeeScript.run = (code, options = {}) ->
options.bare = on
options.shiftLine = on
Function(compile code, options)()
导出比 index.coffee
导出的更有限的 CoffeeScript
,后者是为 Node 环境设计的。
module.exports = CoffeeScript
如果我们不在浏览器环境中,我们就完成了公共 API 的工作。
return unless window?
尽可能包含源映射。如果我们有 base64 编码器、JSON 序列化器和用于转义 Unicode 字符的工具,我们就可以开始了。从 https://developer.mozilla.org/en-US/docs/DOM/window.btoa 移植而来
if btoa? and JSON?
compile = (code, options = {}) ->
options.inlineMap = true
CoffeeScript.compile code, options
通过 XHR 从当前域加载远程脚本。
CoffeeScript.load = (url, callback, options = {}, hold = false) ->
options.sourceFiles = [url]
xhr = if window.ActiveXObject
new window.ActiveXObject('Microsoft.XMLHTTP')
else
new window.XMLHttpRequest()
xhr.open 'GET', url, true
xhr.overrideMimeType 'text/plain' if 'overrideMimeType' of xhr
xhr.onreadystatechange = ->
if xhr.readyState is 4
if xhr.status in [0, 200]
param = [xhr.responseText, options]
CoffeeScript.run param... unless hold
else
throw new Error "Could not load #{url}"
callback param if callback
xhr.send null
通过让浏览器编译和评估所有内容类型为 text/coffeescript
的脚本标签来激活浏览器中的 CoffeeScript。这在页面加载时发生。
CoffeeScript.runScripts = ->
scripts = window.document.getElementsByTagName 'script'
coffeetypes = ['text/coffeescript', 'text/literate-coffeescript']
coffees = (s for s in scripts when s.type in coffeetypes)
index = 0
execute = ->
param = coffees[index]
if param instanceof Array
CoffeeScript.run param...
index++
execute()
for script, i in coffees
do (script, i) ->
options = literate: script.type is coffeetypes[1]
source = script.src or script.getAttribute('data-src')
if source
options.filename = source
CoffeeScript.load source,
(param) ->
coffees[i] = param
execute()
options
true
else
options.filename
定义了源映射在开发者工具中显示的文件名。如果脚本标签有 id
,则使用它作为文件名;否则使用 coffeescript
或 coffeescript1
等,将第一个保留为未编号,以应对只有一个 CoffeeScript 脚本块要解析的常见情况。
options.filename = if script.id and script.id isnt '' then script.id else "coffeescript#{if i isnt 0 then i else ''}"
options.sourceFiles = ['embedded']
coffees[i] = [script.innerHTML, options]
execute()
监听窗口加载事件,无论是在正常的浏览器还是 IE 中。仅在启动时为非 ES 模块版本的浏览器编译器附加此事件处理程序,以保持向后兼容性,同时允许 ES 模块版本在没有副作用的情况下导入。
if this is window
if window.addEventListener
window.addEventListener 'DOMContentLoaded', CoffeeScript.runScripts, no
else
window.attachEvent 'onload', CoffeeScript.runScripts