Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

removed dependency on JCoffeeScript. By passed it, to go directly to

Rhino. This enables having more control over the version of Rhino used,
and the version of CoffeeScript.
  • Loading branch information...
commit abd171571e41e46fbf14f108d0e6c385cb53478d 1 parent 71d36f5
@halfbaked halfbaked authored
View
1  .gitignore
@@ -8,3 +8,4 @@ target/
.settings/
out/
+stacktrace.log
View
15 CoffeescriptResourcesGrailsPlugin.groovy
@@ -1,10 +1,9 @@
-import org.grails.plugins.coffeescript.ModuleManager
import org.springframework.core.io.FileSystemResource
import grails.util.BuildSettingsHolder
import org.grails.plugin.resource.ResourceProcessor
class CoffeescriptResourcesGrailsPlugin {
- def version = "0.2"
+ def version = "0.3.1"
def grailsVersion = "1.3.7 > *"
def dependsOn = [:]
def pluginExcludes = [
@@ -24,27 +23,17 @@ class CoffeescriptResourcesGrailsPlugin {
def issueManagement = [ system: "GitHub", url: "https://github.com/edvinasbartkus/grails-coffeescript-resources/issues" ]
def onChange = { event ->
- def source = event.source
- if(source instanceof FileSystemResource && source.file.name.endsWith(".coffee")) {
- def relativePath = source.file.path - BuildSettingsHolder.settings.baseDir.path
- def modules = ModuleManager.filesHash.get(relativePath)
- if(modules) {
- new ModuleManager().compileModules(modules)
- }
- }
}
def onConfigChange = { event ->
- new ModuleManager().compileModules()
}
def doWithApplicationContext = {
- new ModuleManager().compileModules()
}
def doWithSpring = { ->
ResourceProcessor.DEFAULT_MODULE_SETTINGS['coffee'] = [
- disposition: 'head'
+ disposition: 'defer'
]
}
}
View
25 README.md
@@ -1,7 +1,24 @@
-This is yet another coffeescript compile plugin for Grails framework.
+This is a grails plugin that enables the easy inclusion of coffee script in your Grails web application.
+It requires the well established resources plugin.
-It uses jCoffeeScript to compile .coffee files to .js. No need to have node.js with coffeescript installed on your system to have .coffee files compiled.
+# Background
+As the author says himself "CoffeeScript is a little language that compiles to JavaScript". CoffeeScript is an attempt to make writing JavaScript easier, more elegant, and more efficient.
+
+The standard CoffeeScript compiler runs on NodeJs. This plugin is basically a bridge (via Rhino) to a browser compatible version of the compiler released by Jeremy Ashkenas. It uses CoffeeScript version 1.2.0.
-This plugin is more focused on grouping .coffee files into modules and compiling them into .js files. This is very good when you work with JavaScript MVC frameworks like Backbone which results in separated files for your models, views and controllers. You can find gdoc files to find example how to use it.
+# Usage
+To add coffee script resources to your grails project
-Have any questions: edvinas (et) geeks.lt
+* Install the plugin
+* Actually add your CoffeeScript files to your project. I placed mine adjacent to the js folder in cs.
+* Reference your CoffeeScript files in your ApplicationResources file (or where ever you are defining your resources).
+
+Example
+<pre>
+coffee {
+ resource url: 'cs/views.coffee'
+ resource url: 'cs/models.coffee'
+}
+</pre>
+The above example will create a resource you can include in pages or have another resource depend on. The CoffeeScript files are converted
+to JavaScript, and included like any of your JavaScript files. The default disposition for your CoffeeScript follows the JavaScript default: "defer" - that is they will appear at the end of your page.
View
6 application.properties
@@ -1,7 +1,5 @@
#Grails Metadata file
-#Sat Jan 14 23:51:07 EET 2012
+#Sun Jan 29 11:00:44 CET 2012
app.grails.version=2.0.0
app.name=coffeescript-resources
-plugins.hibernate=2.0.0
-plugins.resources=1.1.6
-plugins.tomcat=2.0.0
+plugins.svn=1.0.1
View
24 grails-app/conf/BuildConfig.groovy
@@ -10,22 +10,18 @@ grails.project.dependency.resolution = {
}
log "warn" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose'
repositories {
- grailsPlugins()
- grailsHome()
grailsCentral()
-
- // uncomment the below to enable remote dependency resolution
- // from public Maven repositories
- //mavenLocal()
- //mavenCentral()
- //mavenRepo "http://snapshots.repository.codehaus.org"
- //mavenRepo "http://repository.codehaus.org"
- //mavenRepo "http://download.java.net/maven/2/"
- //mavenRepo "http://repository.jboss.com/maven2/"
}
dependencies {
- // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.
-
- // runtime 'mysql:mysql-connector-java:5.1.13'
+ // specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.
+ runtime 'org.mozilla:rhino:1.7R3'
}
+ plugins {
+ runtime(":resources:1.1.6")
+ build(":tomcat:$grailsVersion",
+ ":release:1.0.0") {
+ export = false
+ }
+ }
+
}
View
12 grails-app/conf/Config.groovy
@@ -23,15 +23,3 @@ log4j = {
warn 'org.mortbay.log'
}
-// Modules for testing
-/*
-coffeescript.modules = {
- one {
- files "src/coffee/test"
- }
-
- two {
- files "src/coffee/test"
- output "test.js"
- }
-} */
View
24 grails-app/conf/DataSource.groovy
@@ -1,32 +1,44 @@
dataSource {
pooled = true
- driverClassName = "org.hsqldb.jdbcDriver"
+ driverClassName = "org.h2.Driver"
username = "sa"
password = ""
}
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = true
- cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider'
+ cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory'
}
// environment specific settings
environments {
development {
dataSource {
- dbCreate = "create-drop" // one of 'create', 'create-drop','update'
- url = "jdbc:hsqldb:mem:devDB"
+ dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
+ url = "jdbc:h2:mem:devDb;MVCC=TRUE"
}
}
test {
dataSource {
dbCreate = "update"
- url = "jdbc:hsqldb:mem:testDb"
+ url = "jdbc:h2:mem:testDb;MVCC=TRUE"
}
}
production {
dataSource {
dbCreate = "update"
- url = "jdbc:hsqldb:file:prodDb;shutdown=true"
+ url = "jdbc:h2:prodDb;MVCC=TRUE"
+ pooled = true
+ properties {
+ maxActive = -1
+ minEvictableIdleTimeMillis=1800000
+ timeBetweenEvictionRunsMillis=1800000
+ numTestsPerEvictionRun=3
+ testOnBorrow=true
+ testWhileIdle=true
+ testOnReturn=true
+ validationQuery="SELECT 1"
+ }
}
}
}
+
View
9 grails-app/resourceMappers/CoffeeScriptResourceMapper.groovy
@@ -21,8 +21,8 @@ class CoffeeScriptResourceMapper implements GrailsApplicationAware {
log.debug "Compiling coffeescript file ${original} into ${target}"
try {
- String content = new org.jcoffeescript.JCoffeeScriptCompiler().compile(input.text)
- target.write(content)
+ String output = new org.grails.plugins.coffeescript.CoffeeScriptEngine().compile(input.text)
+ target.write(output)
resource.processedFile = target
resource.updateActualUrlFromProcessedFile()
@@ -31,7 +31,10 @@ class CoffeeScriptResourceMapper implements GrailsApplicationAware {
resource.contentType = 'text/javascript'
} catch(Exception e) {
- log.error("Problems compiling CoffeeScript ${resource.originalUrl}")
+ log.error """
+ Problems compiling CoffeeScript ${resource.originalUrl}
+ $e
+ """
e.printStackTrace()
}
}
View
BIN  lib/jcoffeescript-1.1.jar
Binary file not shown
View
72 plugin.xml
@@ -0,0 +1,72 @@
+<plugin name='coffeescript-resources' version='0.3.1' grailsVersion='2.0.0 &gt; *'>
+ <author>Edvinas Bartkus</author>
+ <authorEmail>edvinas@geeks.lt</authorEmail>
+ <title>CoffeeScript Resources</title>
+ <description>Plugin that automatically compiles CoffeeScript to JavaScript and works with the resources plugin.</description>
+ <documentation>http://github.com/edvinasbartkus/grails-coffeescript-resources</documentation>
+ <type>CoffeescriptResourcesGrailsPlugin</type>
+ <resources>
+ <resource>CoffeeScriptResourceMapper</resource>
+ </resources>
+ <repositories>
+ <repository name='http://artifactory.ts.eazybusiness.com/artifactory/repo' url='http://artifactory.ts.eazybusiness.com/artifactory/repo/' />
+ <repository name='http://repo2.maven.org/maven2/' url='http://repo2.maven.org/maven2/' />
+ <repository name='grailsCentral' url='http://plugins.grails.org' />
+ <repository name='http://repo.grails.org/grails/plugins' url='http://repo.grails.org/grails/plugins/' />
+ <repository name='http://repo.grails.org/grails/core' url='http://repo.grails.org/grails/core/' />
+ <repository name='grailsCore' url='http://svn.codehaus.org/grails/trunk/grails-plugins' />
+ <repository name='mavenCentral' url='http://repo1.maven.org/maven2/' />
+ <repository name='Codehaus' url='http://repository.codehaus.org/' />
+ <repository name='http://download.java.net/maven/2/' url='http://download.java.net/maven/2/' />
+ <repository name='ebrRelease' url='http://repository.springsource.com/maven/bundles/release/' />
+ <repository name='ebrExternal' url='http://repository.springsource.com/maven/bundles/external/' />
+ </repositories>
+ <dependencies>
+ <compile>
+ <dependency group='xerces' name='xercesImpl' version='2.9.1' />
+ </compile>
+ <runtime>
+ <dependency group='dnsjava' name='dnsjava' version='2.0.8' />
+ <dependency group='mysql' name='mysql-connector-java' version='5.1.6' />
+ <dependency group='com.saasplex' name='agentsHelper' version='1.0.3' />
+ <dependency group='org.bouncycastle' name='bcprov-jdk16' version='1.46' />
+ <dependency group='org.bouncycastle' name='bctsp-jdk16' version='1.46' />
+ <dependency group='com.lowagie' name='itext' version='2.1.0' />
+ <dependency group='org.springframework' name='spring-test' version='2.5' />
+ <dependency group='org.apache.sshd' name='sshd-core' version='0.2.0' />
+ <dependency group='xmlunit' name='xmlunit' version='1.2' />
+ <dependency group='org.bouncycastle' name='bcmail-jdk16' version='1.46' />
+ <dependency group='com.saasplex' name='resourceManagerClient' version='1.0.3' />
+ <dependency group='org.xhtmlrenderer' name='core-renderer' version='R8' />
+ </runtime>
+ </dependencies>
+ <plugins>
+ <test>
+ <plugin group='org.grails.plugins' name='build-test-data' version='1.1.2' />
+ <plugin group='org.grails.plugins' name='grom' version='0.2.2' />
+ <plugin group='org.grails.plugins' name='code-coverage' version='1.1.8' />
+ </test>
+ <runtime>
+ <plugin group='org.grails.plugins' name='export' version='1.0' />
+ <plugin group='org.grails.plugins' name='hibernate' version='2.0.0' />
+ <plugin group='org.grails.plugins' name='background-thread' version='1.6' />
+ <plugin group='org.grails.plugins' name='zipped-resources' version='1.0' />
+ <plugin group='org.grails.plugins' name='jquery' version='1.7.1' />
+ <plugin group='org.grails.plugins' name='jdbc-pool' version='0.3' />
+ <plugin group='org.grails.plugins' name='cache-headers' version='1.1.5' />
+ <plugin group='org.grails.plugins' name='database-migration' version='1.0' />
+ <plugin group='org.grails.plugins' name='cached-resources' version='1.0' />
+ <plugin group='org.grails.plugins' name='rendering' version='0.4.3' />
+ <plugin group='org.grails.plugins' name='resources' version='1.1.6' />
+ <plugin group='org.grails.plugins' name='mail' version='1.0-SNAPSHOT' />
+ <plugin group='org.grails.plugins' name='rest' version='0.7' />
+ <plugin group='org.grails.plugins' name='svn' version='1.0.1' />
+ <plugin group='org.grails.plugins' name='quartz' version='0.4.2' />
+ </runtime>
+ <build>
+ <plugin group='org.grails.plugins' name='tomcat' version='2.0.0' />
+ </build>
+ </plugins>
+ <runtimePluginRequirements />
+ <behavior />
+</plugin>
View
5 src/docs/guide/1 Introduction to CoffeeScript Resources Plugin.gdoc
@@ -1,5 +0,0 @@
-The Coffee Script Resources plugin is yet another plugin that compiles .coffee files to .js.
-
-This plugin is different that it uses jCoffeeScript.jar to compile. No need to have Node.js with CoffeeScript plugin installed on the system to compile coffee files.
-
-Instead of compiling every file to js this plugin is more focused on bundling coffee files into groups. Groups are colled modules. You can join several coffee files into on compiled js file. It is very useful if use Backbone.js or other MVC framework for your application.
View
27 src/docs/guide/2 Getting Started.gdoc
@@ -1,27 +0,0 @@
-h4. The first step to install the plugin:
-
-{code}
-grails install-plugin coffeescript-resources
-{code}
-
-Open Config.groovy files and create modules you want to be compiled into js.
-
-{code}
-coffeescript.modules = {
- module1 {
- files "src/coffee/module1",
- "src/coffee/anotherfile"
- }
-}
-{code}
-
-The code above will find file module1.coffee and anotherfile.coffee in src/coffee directory. It will join them and compile to module1.js which will be placed in web-app/js directory.
-
-To change the output file you can specify in your module configuration:
-
-{code}
-module2 {
- files "...", ".."
- output "someotherdir/output.js"
-}
-{/code}
View
59 src/groovy/org/grails/plugins/coffeescript/CoffeeScriptEngine.groovy
@@ -0,0 +1,59 @@
+package org.grails.plugins.coffeescript
+
+
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Function;
+import org.mozilla.javascript.JavaScriptException;
+import org.mozilla.javascript.NativeArray;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+import org.mozilla.javascript.tools.shell.Global;
+import org.springframework.core.io.ClassPathResource
+
+
+// CoffeeScript engine uses Mozilla Rhino to compile the CoffeeScript template
+// using existing javascript in-browser compiler
+class CoffeeScriptEngine {
+
+ def Scriptable globalScope
+ def ClassLoader classLoader
+
+ def CoffeeScriptEngine(){
+ try {
+ classLoader = getClass().getClassLoader()
+
+ def coffeeScriptJsResource = (new ClassPathResource('org/grails/plugins/coffeescript/coffee-script-1.2.js', getClass().classLoader))
+ assert coffeeScriptJsResource.exists() : "CoffeeScriptJs resource not found"
+
+ def coffeeScriptJsStream = coffeeScriptJsResource.inputStream
+
+ Context cx = Context.enter()
+ cx.setOptimizationLevel(-1)
+ globalScope = cx.initStandardObjects()
+ cx.evaluateReader(globalScope, new InputStreamReader(coffeeScriptJsStream, 'UTF-8'), coffeeScriptJsResource.filename, 0, null)
+ } catch (Exception e) {
+ throw new Exception("CoffeeScript Engine initialization failed.", e)
+ } finally {
+ try {
+ Context.exit()
+ } catch (java.lang.IllegalStateException e) {}
+ }
+ }
+
+ def compile(String input) {
+ try {
+ def cx = Context.enter()
+ def compileScope = cx.newObject(globalScope)
+ compileScope.setParentScope(globalScope)
+ compileScope.put("coffeeScriptSrc", compileScope, input)
+ def result = cx.evaluateString(compileScope, "CoffeeScript.compile(coffeeScriptSrc)", "CoffeeScript compile command", 0, null)
+ return result
+ } catch (Exception e) {
+ throw new Exception("CoffeeScript Engine compilation failed.", e)
+ } finally {
+ Context.exit()
+ }
+ }
+
+}
+
View
65 src/groovy/org/grails/plugins/coffeescript/CoffeeScriptModule.groovy
@@ -1,65 +0,0 @@
-package org.grails.plugins.coffeescript
-
-import org.codehaus.groovy.grails.web.context.ServletContextHolder
-import grails.util.BuildSettingsHolder
-
-class CoffeeScriptModule {
- String name
- List<String> files
- String output
-
- public CoffeeScriptModule() {
- files = new ArrayList<String>()
- }
-
- def compile() {
- def wholeContent = []
-
- files.each {
- def file = new File(it + ".coffee")
- if(file.exists()) {
- wholeContent << file.getText()
- } else {
- System.out.println("File ${it}.coffee not found for ${name} module!")
- }
- }
-
- def content = wholeContent.join(System.getProperty("line.separator"))
- File outputFile = this.output ? new File(getRealPath(), this.output) : new File(getRealPath("/web-app/js"), "${name}.js")
-
- System.out.println("Compiling ${name} to ${outputFile.absolutePath}.")
-
- def js
- try {
- js = new org.jcoffeescript.JCoffeeScriptCompiler().compile(content)
- } catch (Exception e) {
- def message = e.message
- def pattern = ~/.*Parse error on line (\d+):.*/
- def matcher = pattern.matcher(message)
-
- if (matcher.matches()) {
- def line = matcher[0][1] as Integer
- def range = (line - 3..line + 3)
-
- content.eachLine { l, n ->
- if (range.contains(n + 1)) {
- System.out.println("${n + 1}: ${l}")
- }
- }
-
- System.out.println("Problem in line ${line}. Message: $e.message")
- } else {
- throw e
- }
- }
-
- if(js)
- outputFile.write(js)
- }
-
- def getRealPath(path = "/web-app/js") {
- return new File(BuildSettingsHolder.settings.baseDir, path)
- // return ServletContextHolder.servletContext.getRealPath(path)
- }
-}
-
View
21 src/groovy/org/grails/plugins/coffeescript/ConfigBuilder.groovy
@@ -1,21 +0,0 @@
-package org.grails.plugins.coffeescript
-
-class ConfigBuilder implements GroovyInterceptable {
- ModuleManager manager
-
- def invokeMethod(String name, args) {
- if(args.size() == 1 && args.first() instanceof Closure) {
- CoffeeScriptModule module = manager.modulesHash.get(name)
-
- if(!module) {
- module = new CoffeeScriptModule(name:name)
- manager.modulesHash.put name, module
- }
-
- def moduleClosure = args.first()
- moduleClosure.delegate = new ModuleBuilder(module: module)
- moduleClosure.resolveStrategy = Closure.DELEGATE_FIRST
- moduleClosure()
- }
- }
-}
View
26 src/groovy/org/grails/plugins/coffeescript/ModuleBuilder.groovy
@@ -1,26 +0,0 @@
-package org.grails.plugins.coffeescript
-
-class ModuleBuilder {
- CoffeeScriptModule module
-
- def invokeMethod(String name, args) {
- if(module) {
- switch(name) {
- case "output" :
- if(args.size() > 0) {
- module.output = args.first()
- }
-
- break
- case "files" :
- args.each {
- module.files.push it
- }
-
- break
- default :
- break
- }
- }
- }
-}
View
56 src/groovy/org/grails/plugins/coffeescript/ModuleManager.groovy
@@ -1,56 +0,0 @@
-package org.grails.plugins.coffeescript
-
-import org.codehaus.groovy.grails.commons.ConfigurationHolder as CH
-
-class ModuleManager {
- HashMap<String, CoffeeScriptModule> modulesHash
- static final HashMap<String,String> filesHash = new HashMap<String, String>()
-
- ModuleManager() {
- modulesHash = new HashMap<String, CoffeeScriptModule>()
- }
-
- def getModules() {
- modulesHash = [:]
- filesHash.clear()
-
- def builder = new ConfigBuilder(manager:this)
- CH.config.coffeescript.modules.each { dsl ->
- if(dsl instanceof Closure) {
- dsl.delegate = builder
- dsl.resolveStrategy = Closure.DELEGATE_FIRST
- dsl()
- }
- }
-
- def modules = modulesHash.values()
- modules.each { CoffeeScriptModule module ->
- module.files.each {
- def file = "/${it}.coffee"
- if(!filesHash[file]) {
- filesHash[file] = []
- }
- filesHash[file] << "${module.name}"
- }
- }
-
- return modules.toList()
- }
-
- def compileModules(modules = []) {
- getModules()
- if(modules.isEmpty()) {
- modulesHash.values().collect { it.compile() }
- } else {
- modules.each {
- if(it instanceof CoffeeScriptModule) {
- it.compile()
- } else {
- def module = modulesHash.get(it as String)
- if(module) module.compile()
- }
- }
- }
-
- }
-}
View
9 src/groovy/org/grails/plugins/coffeescript/coffee-script-1.2.js
9 additions, 0 deletions not shown
View
32 test/integration/org/grails/plugins/coffeescript/CoffeeScriptEngineTests.groovy
@@ -0,0 +1,32 @@
+package org.grails.plugins.coffeescript
+
+
+import org.codehaus.groovy.grails.commons.ApplicationHolder
+import org.springframework.core.io.ClassPathResource
+
+
+class CoffeeScriptEngineTests extends grails.test.GrailsUnitTestCase {
+
+ def coffeeScriptEngine
+
+ void setUp(){
+ coffeeScriptEngine = new CoffeeScriptEngine()
+ }
+
+ void testCompile(){
+ def input, output
+ input = """
+ alert "Hello CoffeeScript!"
+ """
+ output = coffeeScriptEngine.compile(input)
+ assert output.contains('alert(') : "Unexpected output: $output"
+
+ input = (new ClassPathResource('org/grails/plugins/coffeeScript/example.coffee', getClass().classLoader)).file.text
+ output = coffeeScriptEngine.compile(input)
+ assert output.contains('number = 42;') : "Output $output"
+
+ }
+
+}
+
+
View
28 test/integration/org/grails/plugins/coffeescript/example.coffee
@@ -0,0 +1,28 @@
+# Assignment:
+number = 42
+opposite = true
+
+# Conditions:
+number = -42 if opposite
+
+# Functions:
+square = (x) -> x * x
+
+# Arrays:
+list = [1, 2, 3, 4, 5]
+
+# Objects:
+math =
+ root: Math.sqrt
+ square: square
+ cube: (x) -> x * square x
+
+# Splats:
+race = (winner, runners...) ->
+ print winner, runners
+
+# Existence:
+alert "I knew it!" if elvis?
+
+# Array comprehensions:
+cubes = (math.cube num for num in list)
Please sign in to comment.
Something went wrong with that request. Please try again.