@@ -26,7 +26,7 @@ import java.util.concurrent.atomic.AtomicBoolean
26
26
27
27
/**
28
28
* Surrounds the filtered text with <script> and CDATA tags.
29
- *
29
+ *
30
30
* <p>Useful for including inline Javascript.</p>
31
31
*
32
32
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
@@ -62,7 +62,7 @@ object CoffeeScriptFilter extends Filter with Log {
62
62
63
63
if (serverSideCompile) {
64
64
try {
65
- Compiler .compile(content, Some (context.currentTemplate)).fold({
65
+ CoffeeScriptCompiler .compile(content, Some (context.currentTemplate)).fold({
66
66
error =>
67
67
warn(" Could not compile coffeescript: " + error, error)
68
68
throw new CompilerException (error.message, Nil )
@@ -83,22 +83,48 @@ object CoffeeScriptFilter extends Filter with Log {
83
83
clientSideCompile
84
84
}
85
85
}
86
+ }
87
+
88
+ /**
89
+ * Compiles a .coffee file into JS on the server side
90
+ */
91
+ object CoffeeScriptPipeline extends Filter with Log {
86
92
87
93
/**
88
- * A Scala / Rhino Coffeescript compiler.
94
+ * Installs the coffeescript pipeline
89
95
*/
90
- object Compiler {
91
-
92
- /**
93
- * Compiles a string of Coffeescript code to Javascript.
94
- *
95
- * @param code the Coffeescript code
96
- * @param sourceName a descriptive name for the code unit under compilation (e.g a filename)
97
- * @param bare if true, no function wrapper will be generated
98
- * @return the compiled Javascript code
99
- */
100
- def compile (code : String , sourceName : Option [String ] = None , bare : Boolean = false )
101
- : Either [CompilationError , String ] = withContext { ctx =>
96
+ def apply (engine : TemplateEngine ) {
97
+ engine.pipelines += " coffee" -> List (NoLayoutFilter (this , " text/javascript" ))
98
+ engine.templateExtensionsFor(" js" ) += " coffee"
99
+ }
100
+
101
+ def filter (context : RenderContext , content : String ) = {
102
+ CoffeeScriptCompiler .compile(content, Some (context.currentTemplate)).fold({
103
+ error =>
104
+ warn(" Could not compile coffeescript: " + error, error)
105
+ throw new CompilerException (error.message, Nil )
106
+ }, {
107
+ coffee => coffee
108
+ })
109
+ }
110
+ }
111
+
112
+ /**
113
+ * A Scala / Rhino Coffeescript compiler.
114
+ */
115
+ object CoffeeScriptCompiler {
116
+
117
+ /**
118
+ * Compiles a string of Coffeescript code to Javascript.
119
+ *
120
+ * @param code the Coffeescript code
121
+ * @param sourceName a descriptive name for the code unit under compilation (e.g a filename)
122
+ * @param bare if true, no function wrapper will be generated
123
+ * @return the compiled Javascript code
124
+ */
125
+ def compile (code : String , sourceName : Option [String ] = None , bare : Boolean = false )
126
+ : Either [CompilationError , String ] = withContext {
127
+ ctx =>
102
128
val scope = ctx.initStandardObjects()
103
129
ctx.evaluateReader(
104
130
scope,
@@ -113,22 +139,20 @@ object CoffeeScriptFilter extends Filter with Log {
113
139
try {
114
140
Right (compileFunc.call(ctx, scope, coffee, Array (code, opts)).asInstanceOf [String ])
115
141
} catch {
116
- case e : JavaScriptException =>
142
+ case e : JavaScriptException =>
117
143
Left (CompilationError (sourceName, e.getValue.toString))
118
144
}
119
- }
145
+ }
120
146
121
- def withContext [T ](f : Context => T ): T = {
122
- val ctx = Context .enter()
123
- try {
124
- ctx.setOptimizationLevel(- 1 ) // Do not compile to byte code (max 64kb methods)
125
- f(ctx)
126
- } finally {
127
- Context .exit()
128
- }
147
+ def withContext [T ](f : Context => T ): T = {
148
+ val ctx = Context .enter()
149
+ try {
150
+ ctx.setOptimizationLevel(- 1 ) // Do not compile to byte code (max 64kb methods)
151
+ f(ctx)
152
+ } finally {
153
+ Context .exit()
129
154
}
130
155
}
131
-
132
- case class CompilationError (sourceName : Option [String ], message : String )
133
156
}
134
157
158
+ case class CompilationError (sourceName : Option [String ], message : String )
0 commit comments