CoffeeScript = require './coffeescript'
{ compile } = CoffeeScript
このブラウザ互換性レイヤーはコア CoffeeScript 関数を拡張して、コードをブラウザで直接コンパイルする際のスムーズな処理を可能にします。XHR および text/coffeescript
スクリプトタグ、データ URL を通じたソースマップなど、リモートの Coffee スクリプトのロードのサポートを追加します。
CoffeeScript = require './coffeescript'
{ compile } = CoffeeScript
eval
ではなく window.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)()
Node 環境用に用意されている index.coffee
ではエクスポートされるCoffeeScriptより、制限されたこのCoffeeScriptをエクスポートします。
module.exports = CoffeeScript
ブラウザ環境内にない場合は、パブリック API はこれで完了です。
return unless window?
可能な限り、ソースマップを含めます。base64 エンコーダ、JSON シリアライザ、およびユニコード文字のエスケープ用のツールがあれば、問題ありません。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
などを使用し、最初の 1 つには番号を付けないようにします(解析する CoffeeScript スクリプトブロックが 1 つしかない一般的なケース)。
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