working with less and css

Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/2bf0c765
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/2bf0c765
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/2bf0c765

Branch: refs/heads/1846-dev-server-improvements
Commit: 2bf0c765d2c6f17ccaf045eb5068ea6dda9166ad
Parents: 8e8b8b2
Author: Garren Smith <[email protected]>
Authored: Tue Jul 2 16:51:44 2013 +0200
Committer: Garren Smith <[email protected]>
Committed: Tue Jul 2 16:51:44 2013 +0200

----------------------------------------------------------------------
 src/fauxton/Gruntfile.js                        |   29 +-
 src/fauxton/app/addons/stats/base.js            |    3 +-
 src/fauxton/app/api.js                          |    2 +-
 src/fauxton/app/config.js                       |   19 +
 src/fauxton/app/main.js                         |    3 +-
 src/fauxton/app/modules/documents/views.js      |    2 +-
 src/fauxton/assets/index.underscore             |    1 -
 .../assets/js/plugins/require-css/LICENSE       |   10 +
 .../assets/js/plugins/require-css/README.md     |  229 +
 .../assets/js/plugins/require-css/bower.json    |    5 +
 .../js/plugins/require-css/css-builder.js       |  251 +
 .../assets/js/plugins/require-css/css.js        |  435 +
 .../js/plugins/require-css/example/build.js     |   31 +
 .../js/plugins/require-css/example/setup.sh     |    5 +
 .../js/plugins/require-css/example/test.html    |   30 +
 .../js/plugins/require-css/example/www/app.js   |    4 +
 .../example/www/components/component.css        |    5 +
 .../example/www/components/component.js         |    3 +
 .../require-css/example/www/components/test.css |    3 +
 .../plugins/require-css/example/www/jquery.js   | 9404 ++++++++++++++++++
 .../plugins/require-css/example/www/popup.css   |    7 +
 .../js/plugins/require-css/example/www/popup.js |    3 +
 .../plugins/require-css/example/www/require-css |    1 +
 .../require-css/example/www/style/style.css     |    6 +
 .../js/plugins/require-css/example/www/test.css |    3 +
 .../plugins/require-css/example/www/test.html   |   28 +
 .../js/plugins/require-css/example/www/text.js  |  282 +
 .../assets/js/plugins/require-css/normalize.js  |  138 +
 .../assets/js/plugins/require-css/package.json  |    5 +
 .../assets/js/plugins/require-css/test/test.js  |   78 +
 .../assets/js/plugins/require-less/LICENSE      |   10 +
 .../assets/js/plugins/require-less/README.md    |   68 +
 .../assets/js/plugins/require-less/bower.json   |    4 +
 .../js/plugins/require-less/example/build.js    |   30 +
 .../js/plugins/require-less/example/setup.sh    |    3 +
 .../js/plugins/require-less/example/test.html   |   29 +
 .../js/plugins/require-less/example/www/app.js  |    3 +
 .../example/www/components/component.js         |    3 +
 .../example/www/components/component.less       |    5 +
 .../require-less/example/www/css-style.css      |    3 +
 .../example/www/less-style/style.less           |    4 +
 .../example/www/less-style/test.less            |    1 +
 .../require-less/example/www/require-css        |    1 +
 .../require-less/example/www/require-less       |    1 +
 .../plugins/require-less/example/www/test.html  |   29 +
 .../js/plugins/require-less/example/www/text.js |  282 +
 .../js/plugins/require-less/less-builder.js     |   42 +
 .../assets/js/plugins/require-less/less.js      |   46 +
 .../js/plugins/require-less/lessc-server.js     |   96 +
 .../assets/js/plugins/require-less/lessc.js     | 4441 +++++++++
 .../assets/js/plugins/require-less/package.json |   18 +
 src/fauxton/package.json                        |    9 +-
 src/fauxton/tasks/couchserver.js                |    5 +-
 53 files changed, 16143 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/2bf0c765/src/fauxton/Gruntfile.js
----------------------------------------------------------------------
diff --git a/src/fauxton/Gruntfile.js b/src/fauxton/Gruntfile.js
index a89453a..2a3fe96 100644
--- a/src/fauxton/Gruntfile.js
+++ b/src/fauxton/Gruntfile.js
@@ -154,7 +154,8 @@ module.exports = function(grunt) {
     // index.html.
     concat: {
       requirejs: {
-        src: [ "dist/debug/templates.js", "assets/js/libs/require.js"],
+       // src: [ "dist/debug/templates.js", "assets/js/libs/require.js"],
+        src: [ "assets/js/libs/require.js"],
         dest: "dist/debug/js/require.js"
       },
 
@@ -207,7 +208,7 @@ module.exports = function(grunt) {
 
     watch: {
       files: './app/**/*',
-      tasks: ['debug', 'template']
+      tasks: ['watchRun']
     },
 
     requirejs: {
@@ -225,8 +226,10 @@ module.exports = function(grunt) {
 
           // Do not wrap everything in an IIFE.
           wrap: false,
-          optimize: "none"
-      }
+          optimize: "none",
+          excludeShallow: ['css/css-builder', 'less/lessc-server', 
'less/lessc'],
+          include: ['css']
+        }
       }
     },
 
@@ -302,11 +305,23 @@ module.exports = function(grunt) {
   // Load the couchapp task
   grunt.loadNpmTasks('grunt-couchapp');
   // Load the copy task
-  grunt.loadNpmTasks('grunt-contrib');
+  grunt.loadNpmTasks('grunt-contrib-watch');
   // Load the exec task
   grunt.loadNpmTasks('grunt-exec');
   // Load Require.js task
   grunt.loadNpmTasks('grunt-requirejs');
+  // Load Copy task
+  grunt.loadNpmTasks('grunt-contrib-copy');
+  // Load Clean task
+  grunt.loadNpmTasks('grunt-contrib-clean');
+  // Load jshint task
+  grunt.loadNpmTasks('grunt-contrib-jshint');
+  // Load jst task
+  grunt.loadNpmTasks('grunt-contrib-jst');
+  // Load less task
+  grunt.loadNpmTasks('grunt-contrib-less');
+  // Load concat task
+  grunt.loadNpmTasks('grunt-contrib-concat');
   // Load UglifyJS task
   grunt.loadNpmTasks('grunt-contrib-uglify');
   // Load CSSMin task
@@ -336,7 +351,9 @@ module.exports = function(grunt) {
   // dev server
   grunt.registerTask('dev', ['debug', 'couchserver']);
   // build a debug release
-  grunt.registerTask('debug', ['test', 'dependencies', 'build', 'copy:debug']);
+  grunt.registerTask('debug', ['test', 'dependencies', 
'concat:requirejs','less', 'concat:index_css', 'template', 'copy:debug']);
+  //grunt.registerTask('watchRun', ['jshint', 'dependencies', 'less', 
'concat:index_css' ]);
+  grunt.registerTask('watchRun', ['jshint', 'dependencies' ]);
   // build a release
   grunt.registerTask('release', ['test' ,'dependencies', 'build', 'minify', 
'copy:dist']);
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2bf0c765/src/fauxton/app/addons/stats/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/stats/base.js 
b/src/fauxton/app/addons/stats/base.js
index 4721399..78e4994 100644
--- a/src/fauxton/app/addons/stats/base.js
+++ b/src/fauxton/app/addons/stats/base.js
@@ -13,7 +13,8 @@
 define([
   "app",
   "api",
-  "addons/stats/routes"
+  "addons/stats/routes",
+  'less!/app/addons/stats/assets/less/stats'
 ],
 
 function(app, FauxtonAPI, Stats) {

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2bf0c765/src/fauxton/app/api.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/api.js b/src/fauxton/app/api.js
index 58c413d..a2b62dd 100644
--- a/src/fauxton/app/api.js
+++ b/src/fauxton/app/api.js
@@ -78,7 +78,7 @@ function(app, Fauxton) {
     }
 
     return $.when(deferreds);
-  },
+  };
 
   FauxtonAPI.addRoute = function(route) {
     app.router.route(route.route, route.name, route.callback);

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2bf0c765/src/fauxton/app/config.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/config.js b/src/fauxton/app/config.js
index c7ae1d6..97b8ea2 100644
--- a/src/fauxton/app/config.js
+++ b/src/fauxton/app/config.js
@@ -50,6 +50,25 @@ require.config({
     "plugins/prettify": [],
 
     "plugins/jquery.form": ["jquery"]
+  },
+
+  /*map: {
+    '*': {
+      'css': '../assets/js/plugins/require-css/css'
+    }
+  },*/
+
+  packages: [
+  {
+    name: 'css',
+    location: '../assets/js/plugins/require-css',
+    main: 'css'
+  },
+  {
+    name: 'less',
+    location: '../assets/js/plugins/require-less',
+    main: 'less'
   }
+]
 
 });

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2bf0c765/src/fauxton/app/main.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/main.js b/src/fauxton/app/main.js
index 203b295..1313bb9 100644
--- a/src/fauxton/app/main.js
+++ b/src/fauxton/app/main.js
@@ -1,4 +1,5 @@
 require([
+  'css!/css/index',
   // Application.
   "app",
 
@@ -6,7 +7,7 @@ require([
   "router"
 ],
 
-function(app, Router) {
+function(indexCSS, app, Router) {
 
   // Define your master router on the application namespace and trigger all
   // navigation from this instance.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2bf0c765/src/fauxton/app/modules/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/modules/documents/views.js 
b/src/fauxton/app/modules/documents/views.js
index 59e3b7d..6c92cfa 100644
--- a/src/fauxton/app/modules/documents/views.js
+++ b/src/fauxton/app/modules/documents/views.js
@@ -764,7 +764,7 @@ function(app, FauxtonAPI, Documents, pouchdb, Codemirror, 
JSHint) {
 
       var that = this,
           promise,
-          viewName = this.$('#index-name').val();
+          viewName = this.$('#index-name').val(),
           ddocName = this.$('#ddoc :selected').val(),
           ddoc = this.getCurrentDesignDoc();
 

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2bf0c765/src/fauxton/assets/index.underscore
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/index.underscore 
b/src/fauxton/assets/index.underscore
index bc2fdf2..862fa2c 100644
--- a/src/fauxton/assets/index.underscore
+++ b/src/fauxton/assets/index.underscore
@@ -24,7 +24,6 @@
   <title>Project Fauxton</title>
 
   <!-- Application styles. -->
-  <link rel="stylesheet" href="<%= assets_root %>css/index.css">
   <style type="text/css">
     body {
     padding-top: 60px;

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2bf0c765/src/fauxton/assets/js/plugins/require-css/LICENSE
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/plugins/require-css/LICENSE 
b/src/fauxton/assets/js/plugins/require-css/LICENSE
new file mode 100644
index 0000000..e39e77c
--- /dev/null
+++ b/src/fauxton/assets/js/plugins/require-css/LICENSE
@@ -0,0 +1,10 @@
+MIT License
+-----------
+
+Copyright (C) 2013 Guy Bedford
+
+Permission is hereby granted, free of charge, to any person obtaining a copy 
of this software and associated documentation files (the "Software"), to deal 
in the Software without restriction, including without limitation the rights to 
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
of the Software, and to permit persons to whom the Software is furnished to do 
so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all 
copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
SOFTWARE.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2bf0c765/src/fauxton/assets/js/plugins/require-css/README.md
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/plugins/require-css/README.md 
b/src/fauxton/assets/js/plugins/require-css/README.md
new file mode 100644
index 0000000..4cb0869
--- /dev/null
+++ b/src/fauxton/assets/js/plugins/require-css/README.md
@@ -0,0 +1,229 @@
+require-css
+===========
+
+RequireJS CSS requiring and optimization.
+
+Useful for writing modular CSS dependencies alongside scripts. For an example 
of widget rendering see [ZestJS](http://zestjs.org).
+
+For LESS inclusion, use 
[require-less](https://github.com/guybedford/require-less), which behaves and 
builds the css exactly like this module apart from the preprocessing step.
+
+Overview
+--------
+
+Allows the construction of scripts that can require CSS, using the simple 
RequireJS syntax:
+
+```javascript
+define(['css!styles/main'], function() {
+  //code that requires the stylesheet: styles/main.css
+});
+```
+
+### CSS Requiring
+* Fully compatible in IE 6 - 10, Chrome 3 - 26, Firefox 3.5 - 19, Opera 10 - 
12, iOS, Android
+* Cross-domain style loading
+* Line numbers in dev inspector correlate with correct CSS file
+
+### CSS Building
+* **CSS builds** When run as part of a build with the RequireJS optimizer, 
`css!` dependencies are automatically inlined into the built layer within the 
JavaScript, fully compatible with layering. CSS injection is performed as soon 
as the layer is loaded.
+* **Option to build separate layer CSS files** A `separateCSS` build parameter 
allows for built layers to output their css files separately, instead of inline 
with the JavaScript, for manual inclusion.
+* **CSS compression** CSS redundancy compression is supported through the 
external library, [csso](https://github.com/css/csso).
+
+Installation and Setup
+----------------------
+
+Download the require-css folder manually or use 
[volo](https://github.com/volojs/volo)(`npm install volo -g`):
+
+```bash
+volo add guybedford/require-css
+```
+
+To allow the direct `css!` usage, add the following [map 
configuration](http://requirejs.org/docs/api.html#config-map) in RequireJS:
+
+```javascript
+map: {
+  '*': {
+    'css': 'require-css/css' // or whatever the path to require-css is
+  }
+}
+```
+
+Use Cases and Benefits
+----------------------
+
+### Motivation
+
+The use case for RequireCSS came out of a need to manage templates and their 
CSS together. 
+The idea being that a CSS require can be a dependency of the code that 
dynamically renders a template. 
+When writing a large dynamic application, with templates being rendered on the 
client-side, it can be beneficial to inject the CSS as templates are required 
instead 
+of dumping all the CSS together separately. The added benefit of this is then 
being able to build the CSS naturally with the RequireJS optimizer, 
+which also supports [separate build 
layers](http://requirejs.org/docs/1.0/docs/faq-optimization.html#priority) as 
needed.
+
+### Script-inlined CSS Benefits
+
+By default, during the build CSS is compressed and inlined as a string within 
the layer that injects the CSS when run.
+
+If the layer is included as a `<script>` tag, only one browser request is 
needed instead of many separate CSS requests with `<link>` tags.
+
+Even better than including a layer as a `<script>` tag is to include the layer 
dynamically with a non-blocking require. 
+Then the page can be displayed while the layer is still loading asynchronously 
in the background. 
+In this case, the CSS that goes with a template being dynamically rendered is 
loaded with that same script asynchronously. 
+No longer does it need to sit in a `<link>` tag that blocks the page display 
unnecessarily.
+
+Modular CSS
+-----------
+
+RequireCSS implies a CSS modularisation where styles can be scoped directly to 
the render code that they are bundled with.
+
+Just like JS requires, the order of CSS injection can't be guaranteed. The 
idea here is that whenever there are style overrides, they should
+be based on using a more specific selector with an extra id or class at the 
base, and not assuming a CSS load order. Reset and global styles are a repeated 
dependency of all 
+modular styles that build on top of them.
+
+Optimizer Configuration
+-----------------------
+
+### Basic Usage
+
+Optimizer configuration:
+
+```javascript
+{
+  modules: [
+  {
+    name: 'mymodule'
+  }
+  ]
+}
+```
+
+If the contents of 'mymodule' are:
+
+```javascript
+  define(['css!style', 'css!page'], function(css) {
+    //...
+  });
+```
+
+Then the optimizer output would be:
+
+-mymodule.js containing:
+ style.css and page.css which will be dynamically injected
+ 
+### Configuration Notes
+
+In order for the layer to inject the CSS it will make a runtime require to 
`css`. It is important to ensure that the
+map configuration locating `css` is provided before this injection in the 
script.
+
+If using the standard configuration pattern:
+
+main.js:
+```javascript
+  requirejs.config({
+    map: {
+      '*': {
+        'css': 'require-css/css'
+      }
+    }
+  });
+  require(['app']);
+```
+
+then the configuration will be written by the optimizer as the last item in 
the layer, meaning the `css` module will not be located in
+time for injection.
+
+To ensure this doesn't happen, use the following configuration pattern:
+
+main.js:
+```javascript
+  require(['config'], function() {
+    require(['app']);
+  });
+```
+
+Or build the config first into layer using the `create` and `include` build 
properties.
+
+[More details 
here](https://github.com/jrburke/requirejs/pull/595#issuecomment-16346519)
+
+### Separate File Output
+
+To output the CSS to a separate file, use the configuration:
+
+```javascript
+{
+  separateCSS: true,
+  modules: [
+  {
+    name: 'mymodule'
+  }
+  ]
+}
+```
+
+This will then output all the css to the file `mymodule.css`. This 
configuration can also be placed on the module object itself for layer-specific 
settings.
+
+Optimization is fully compatible with exclude and include.
+
+**Note: Optimization will only work when using r.js version 2.1.0 or later 
(released Oct 4 2012)**
+
+
+CSS Compression
+---------------
+
+CSS compression is supported with [csso](https://github.com/css/csso).
+
+To enable the CSS compression, install csso with npm:
+
+```
+  npm install csso -g
+```
+
+The build log will display the compression results.
+
+When running the r.js optimizer through NodeJS, sometimes the global module 
isn't found. In this case install csso as a local node module so it can be 
found.
+
+
+Conditional CSS
+---
+
+Some styles are conditional on the environment. For example mobile stylesheets 
and IE-specific stylesheets.
+
+To manage this, use the [Require-IS](https://github.com/guybedford/require-is) 
module. 
+
+With Require-IS, one can do:
+
+```javascript
+require(['is!mobile?css!mobile-css'], function(css) {
+  //...
+});
+```
+
+Mobile detection can be defined through a detection script in Require-IS, such 
as:
+
+mobile.js:
+```javascript
+define(function() {
+  return navigator.userAgent.match(/iPhone/); //(just iphone detection as an 
example)
+});
+```
+
+Separate build layers can then be made for mobile specific use. Read more at 
the [Require-IS](https://github.com/guybedford/require-is) project page.
+
+Injection methods
+-----------------
+
+* When loading a CSS file or external CSS file, a `<link>` tag is used. 
Cross-browser support comes through a number of careful browser conditions for 
this.
+* When using Require-LESS parsing or when injecting CSS from the built 
`<script>` tag, a CSS `<style>` injection is used.
+
+If CSS resources such as images are important to be loaded first, these can be 
added to the require through a loader plugin that can act as a preloader such 
as [image](https://github.com/millermedeiros/requirejs-plugins) or 
[font](https://github.com/millermedeiros/requirejs-plugins). Then a require can 
be written of the form:
+
+```javascript
+require(['css!my-css', 'image!preload-background-image.jpg', 
'font!google,families:[Tangerine]']);
+```
+
+Roadmap
+-------
+* ~~Comprehensive CSS minification including style reduction~~
+* ~~LESS extension~~
+* Sprite compilation
+* Source maps?
+
+Suggestions always appreciated - feel free to post a feature request.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2bf0c765/src/fauxton/assets/js/plugins/require-css/bower.json
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/plugins/require-css/bower.json 
b/src/fauxton/assets/js/plugins/require-css/bower.json
new file mode 100644
index 0000000..425c7f2
--- /dev/null
+++ b/src/fauxton/assets/js/plugins/require-css/bower.json
@@ -0,0 +1,5 @@
+{
+  "name": "require-css",
+  "version": "0.0.6",
+  "ignore": ["example", "test", ".gitignore"]
+}

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2bf0c765/src/fauxton/assets/js/plugins/require-css/css-builder.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/plugins/require-css/css-builder.js 
b/src/fauxton/assets/js/plugins/require-css/css-builder.js
new file mode 100644
index 0000000..766aee7
--- /dev/null
+++ b/src/fauxton/assets/js/plugins/require-css/css-builder.js
@@ -0,0 +1,251 @@
+define(['require', './normalize'], function(req, normalize) {
+  var nodePrint = function() {};
+  if (requirejs.tools)
+    requirejs.tools.useLib(function(req) {
+      req(['node/print'], function(_nodePrint) {
+        nodePrint = _nodePrint;
+      }, function(){});
+    });
+  
+  var cssAPI = {};
+  
+  function compress(css) {
+    if (typeof process !== "undefined" && process.versions && 
!!process.versions.node && require.nodeRequire) {
+      try {
+        var csso = require.nodeRequire('csso');
+        var csslen = css.length;
+        css = csso.justDoIt(css);
+        nodePrint('Compressed CSS output to ' + Math.round(css.length / csslen 
* 100) + '%.');
+        return css;
+      }
+      catch(e) {
+        nodePrint('Compression module not installed. Use "npm install csso -g" 
to enable.');
+        return css;
+      }
+    }
+    nodePrint('Compression not supported outside of nodejs environments.');
+    return css;
+  }
+  
+  //load file code - stolen from text plugin
+  function loadFile(path) {
+    if (typeof process !== "undefined" && process.versions && 
!!process.versions.node && require.nodeRequire) {
+      var fs = require.nodeRequire('fs');
+      var file = fs.readFileSync(path, 'utf8');
+      if (file.indexOf('\uFEFF') === 0)
+        return file.substring(1);
+      return file;
+    }
+    else {
+      var file = new java.io.File(path),
+        lineSeparator = java.lang.System.getProperty("line.separator"),
+        input = new java.io.BufferedReader(new java.io.InputStreamReader(new 
java.io.FileInputStream(file), 'utf-8')),
+        stringBuffer, line;
+      try {
+        stringBuffer = new java.lang.StringBuffer();
+        line = input.readLine();
+        if (line && line.length() && line.charAt(0) === 0xfeff)
+          line = line.substring(1);
+        stringBuffer.append(line);
+        while ((line = input.readLine()) !== null) {
+          stringBuffer.append(lineSeparator).append(line);
+        }
+        return String(stringBuffer.toString());
+      }
+      finally {
+        input.close();
+      }
+    }
+  }
+  
+  
+  function saveFile(path, data) {
+    if (typeof process !== "undefined" && process.versions && 
!!process.versions.node && require.nodeRequire) {
+      var fs = require.nodeRequire('fs');
+      fs.writeFileSync(path, data, 'utf8');
+    }
+    else {
+      var content = new java.lang.String(data);
+      var output = new java.io.BufferedWriter(new 
java.io.OutputStreamWriter(new java.io.FileOutputStream(path), 'utf-8'));
+  
+      try {
+        output.write(content, 0, content.length());
+        output.flush();
+      }
+      finally {
+        output.close();
+      }
+    }
+  }
+  
+  //when adding to the link buffer, paths are normalised to the baseUrl
+  //when removing from the link buffer, paths are normalised to the output 
file path
+  function escape(content) {
+    return content.replace(/(["'\\])/g, '\\$1')
+      .replace(/[\f]/g, "\\f")
+      .replace(/[\b]/g, "\\b")
+      .replace(/[\n]/g, "\\n")
+      .replace(/[\t]/g, "\\t")
+      .replace(/[\r]/g, "\\r");
+  }
+
+  // NB add @media query support for media imports
+  var importRegEx = 
/@import\s*(url)?\s*(('([^']*)'|"([^"]*)")|\(('([^']*)'|"([^"]*)"|([^\)]*))\))\s*;?/g;
+
+  var loadCSSFile = function(fileUrl) {
+    var css = loadFile(fileUrl);
+
+    // normalize the css (except import statements)
+    css = normalize(css, fileUrl, baseUrl, cssBase);
+
+    // detect all import statements in the css and normalize
+    var importUrls = [];
+    var importIndex = [];
+    var importLength = [];
+    var match;
+    while (match = importRegEx.exec(css)) {
+      var importUrl = match[4] || match[5] || match[7] || match[8] || match[9];
+
+      // normalize import url
+      if (importUrl.substr(importUrl.length - 5, 5) != '.less' && 
importUrl.substr(importUrl.length - 4, 4) != '.css')
+        importUrl += '.css';
+
+      // contains a protocol
+      if (importUrl.match(/:\/\//))
+        continue;
+
+      // relative to css base
+      if (importUrl.substr(0, 1) == '/' && cssBase)
+        importUrl = cssBase + importUrl;
+      else
+        importUrl = baseUrl + importUrl;
+
+      importUrls.push(importUrl);
+      importIndex.push(importRegEx.lastIndex - match[0].length);
+      importLength.push(match[0].length);
+    }
+
+    // load the import stylesheets and substitute into the css
+    for (var i = 0; i < importUrls.length; i++)
+      (function(i) {
+        var importCSS = loadCSSFile(importUrls[i]);
+        css = css.substr(0, importIndex[i]) + importCSS + 
css.substr(importIndex[i] + importLength[i]);
+        var lenDiff = importCSS.length - importLength[i];
+        for (var j = i + 1; j < importUrls.length; j++)
+          importIndex[j] += lenDiff;
+      })(i);
+
+    return css;
+  }
+  
+
+  var baseUrl;  
+  var cssBase;
+  var curModule;
+  cssAPI.load = function(name, req, load, config, parse) {
+    if (!baseUrl)
+      baseUrl = config.baseUrl;
+    
+    if (!cssBase)
+      cssBase = config.cssBase;
+
+    if (config.modules) {
+      //run through the module list - the first one without a layer set is the 
current layer we are in
+      //allows to track the current layer number for layer-specific config
+      for (var i = 0; i < config.modules.length; i++)
+        if (config.modules[i].layer === undefined) {
+          curModule = i;
+          break;
+        }
+    }
+    
+    //store config
+    cssAPI.config = cssAPI.config || config;
+
+    name += !parse ? '.css' : '.less';
+
+    var fileUrl = req.toUrl(name);
+
+    //external URLS don't get added (just like JS requires)
+    if (fileUrl.substr(0, 7) == 'http://' || fileUrl.substr(0, 8) == 
'https://')
+      return;
+
+    //add to the buffer
+    _cssBuffer[name] = loadCSSFile(fileUrl);
+
+    // parse if necessary
+    if (parse)
+      _cssBuffer[name] = parse(_cssBuffer[name]);
+
+    load();
+  }
+  
+  cssAPI.normalize = function(name, normalize) {
+    if (name.substr(name.length - 4, 4) == '.css')
+      name = name.substr(0, name.length - 4);
+    return normalize(name);
+  }
+  
+  //list of cssIds included in this layer
+  var _layerBuffer = [];
+  var _cssBuffer = [];
+  cssAPI.write = function(pluginName, moduleName, write, parse) {
+    //external URLS don't get added (just like JS requires)
+    if (moduleName.substr(0, 7) == 'http://' || moduleName.substr(0, 8) == 
'https://' || moduleName.substr(0, 2) == '//')
+      return;
+    
+    var resourceName = moduleName + (!parse ? '.css' : '.less');
+    _layerBuffer.push(_cssBuffer[resourceName]);
+
+    var separateCSS = false;
+    if (cssAPI.config.separateCSS)
+      separateCSS = true;
+    if (typeof curModule == 'number' && 
cssAPI.config.modules[curModule].separateCSS !== undefined)
+      separateCSS = cssAPI.config.modules[curModule].separateCSS;
+    if (separateCSS)
+      write.asModule(pluginName + '!' + moduleName, 'define(function(){})');
+    else
+      write("requirejs.s.contexts._.nextTick = function(f){f()}; 
require(['css'], function(css) { css.addBuffer('" + resourceName + "'); }); 
requirejs.s.contexts._.nextTick = requirejs.nextTick;");
+  }
+  
+  cssAPI.onLayerEnd = function(write, data, parser) {
+    firstWrite = true;
+    //separateCSS parameter set either globally or as a layer setting
+    var separateCSS = false;
+    if (cssAPI.config.separateCSS)
+      separateCSS = true;
+    if (typeof curModule == 'number' && 
cssAPI.config.modules[curModule].separateCSS !== undefined)
+      separateCSS = cssAPI.config.modules[curModule].separateCSS;
+    curModule = null;
+    
+    //calculate layer css
+    var css = _layerBuffer.join('');
+    
+    if (separateCSS) {
+      nodePrint('Writing CSS! file: ' + data.name + '\n');
+      
+      //calculate the css output path for this layer
+      var path = this.config.appDir ? this.config.baseUrl + data.name + '.css' 
: cssAPI.config.out.replace(/\.js$/, '.css');
+      
+      //renormalize the css to the output path
+      var output = compress(normalize(css, baseUrl, path));
+      
+      saveFile(path, output);
+    }
+    else {
+      if (css == '')
+        return;
+      //write the injection and layer index into the layer
+      //prepare the css
+      css = escape(compress(css));
+      
+      //the code below overrides async require functionality to ensure instant 
buffer injection
+      write("requirejs.s.contexts._.nextTick = function(f){f()}; 
require(['css'], function(css) { css.setBuffer('" + css + (parser ? "', true" : 
"'") + "); }); requirejs.s.contexts._.nextTick = requirejs.nextTick; ");
+    }
+    
+    //clear layer buffer for next layer
+    _layerBuffer = [];
+  }
+  
+  return cssAPI;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2bf0c765/src/fauxton/assets/js/plugins/require-css/css.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/plugins/require-css/css.js 
b/src/fauxton/assets/js/plugins/require-css/css.js
new file mode 100644
index 0000000..40337c0
--- /dev/null
+++ b/src/fauxton/assets/js/plugins/require-css/css.js
@@ -0,0 +1,435 @@
+/*
+ * Require-CSS RequireJS css! loader plugin
+ * Guy Bedford 2013
+ * MIT
+ */
+
+/*
+ *
+ * Usage:
+ *  require(['css!./mycssFile']);
+ *
+ * NB leave out the '.css' extension.
+ *
+ * - Fully supports cross origin CSS loading
+ * - Works with builds
+ *
+ * Tested and working in (up to latest versions as of March 2013):
+ * Android
+ * iOS 6
+ * IE 6 - 10
+ * Chome 3 - 26
+ * Firefox 3.5 - 19
+ * Opera 10 - 12
+ * 
+ * browserling.com used for virtual testing environment
+ *
+ * Credit to B Cavalier & J Hann for the elegant IE 6 - 9 hack.
+ * 
+ * Sources that helped along the way:
+ * - 
https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent
+ * - http://www.phpied.com/when-is-a-stylesheet-really-loaded/
+ * - https://github.com/cujojs/curl/blob/master/src/curl/plugin/css.js
+ *
+ */
+
+define(['./normalize'], function(normalize) {
+  function indexOf(a, e) { for (var i=0, l=a.length; i < l; i++) if (a[i] === 
e) return i; return -1 }
+
+  if (typeof window == 'undefined')
+    return { load: function(n, r, load){ load() } };
+
+  // set to true to enable test prompts for device testing
+  var testing = false;
+  
+  var head = document.getElementsByTagName('head')[0];
+
+  var engine = window.navigator.userAgent.match(/Trident\/([^ 
;]*)|AppleWebKit\/([^ ;]*)|Opera\/([^ ;]*)|rv\:([^ ;]*)(.*?)Gecko\/([^ 
;]*)|MSIE\s([^ ;]*)/);
+  var hackLinks = false;
+
+  if (!engine) {}
+  else if (engine[1] || engine[7]) {
+    hackLinks = parseInt(engine[1]) < 6 || parseInt(engine[7]) <= 9;
+    engine = 'trident';
+  }
+  else if (engine[2]) {
+    // unfortunately style querying still doesnt work with onload callback in 
webkit
+    hackLinks = true;
+    engine = 'webkit';
+  }
+  else if (engine[3]) {
+    // engine = 'opera';
+  }
+  else if (engine[4]) {
+    hackLinks = parseInt(engine[4]) < 18;
+    engine = 'gecko';
+  }
+  else if (testing)
+    alert('Engine detection failed');
+  
+  //main api object
+  var cssAPI = {};
+
+  var absUrlRegEx = /^\/|([^\:\/]*:)/;
+  
+  cssAPI.pluginBuilder = './css-builder';
+
+  // used by layer builds to register their css buffers
+  
+  // the current layer buffer items (from addBuffer)
+  var curBuffer = [];
+
+  // the callbacks for buffer loads
+  var onBufferLoad = {};
+
+  // the full list of resources in the buffer
+  var bufferResources = [];
+
+  cssAPI.addBuffer = function(resourceId) {
+    // just in case layer scripts are included twice, also check
+    // against the previous buffers
+    if (indexOf(curBuffer, resourceId) != -1)
+      return;
+    if (indexOf(bufferResources, resourceId) != -1)
+      return;
+    curBuffer.push(resourceId);
+    bufferResources.push(resourceId);
+  }
+  cssAPI.setBuffer = function(css, isLess) {
+    var pathname = window.location.pathname.split('/');
+    pathname.pop();
+    pathname = pathname.join('/') + '/';
+
+    var baseParts = require.toUrl('base_url').split('/');
+    baseParts.pop();
+    var baseUrl = baseParts.join('/') + '/';
+    baseUrl = normalize.convertURIBase(baseUrl, pathname, '/');
+    if (!baseUrl.match(absUrlRegEx))
+      baseUrl = '/' + baseUrl;
+    if (baseUrl.substr(baseUrl.length - 1, 1) != '/')
+      baseUrl = baseUrl + '/';
+
+    cssAPI.inject(normalize(css, baseUrl, pathname));
+
+    // set up attach callback if registered
+    // clear the current buffer for the next layer
+    // (just the less or css part as we have two buffers in one effectively)
+    for (var i = 0; i < curBuffer.length; i++) {
+      // find the resources in the less or css buffer dependening which one 
this is
+      if ((isLess && curBuffer[i].substr(curBuffer[i].length - 5, 5) == 
'.less') ||
+        (!isLess && curBuffer[i].substr(curBuffer[i].length - 4, 4) == 
'.css')) {
+        (function(resourceId) {
+          // mark that the onBufferLoad is about to be called (set to true if 
not already a callback function)
+          onBufferLoad[resourceId] = onBufferLoad[resourceId] || true;
+
+          // set a short timeout (as injection isn't instant in Chrome), then 
call the load
+          setTimeout(function() {
+            if (typeof onBufferLoad[resourceId] == 'function')
+              onBufferLoad[resourceId]();
+            // remove from onBufferLoad to indicate loaded
+            delete onBufferLoad[resourceId];
+          }, 7);
+        })(curBuffer[i]);
+
+        // remove the current resource from the buffer
+        curBuffer.splice(i--, 1);
+      }
+    }
+  }
+  cssAPI.attachBuffer = function(resourceId, load) {
+    // attach can happen during buffer collecting, or between injection and 
callback
+    // we assume it is not possible to attach multiple callbacks
+    // requirejs plugin load function ensures this by queueing duplicate calls
+
+    // check if the resourceId is in the current buffer
+    for (var i = 0; i < curBuffer.length; i++)
+      if (curBuffer[i] == resourceId) {
+        onBufferLoad[resourceId] = load;
+        return true;
+      }
+
+    // check if the resourceId is waiting for injection callback
+    // (onBufferLoad === true is a shortcut indicator for this)
+    if (onBufferLoad[resourceId] === true) {
+      onBufferLoad[resourceId] = load;
+      return true;
+    }
+
+    // if it's in the full buffer list and not either of the above, its loaded 
already
+    if (indexOf(bufferResources, resourceId) != -1) {
+      load();
+      return true;
+    }
+  }
+
+  var webkitLoadCheck = function(link, callback) {
+    setTimeout(function() {
+      for (var i = 0; i < document.styleSheets.length; i++) {
+        var sheet = document.styleSheets[i];
+        if (sheet.href == link.href)
+          return callback();
+      }
+      webkitLoadCheck(link, callback);
+    }, 10);
+  }
+
+  var mozillaLoadCheck = function(style, callback) {
+    setTimeout(function() {
+      try {
+        style.sheet.cssRules;
+        return callback();
+      } catch (e){}
+      mozillaLoadCheck(style, callback);
+    }, 10);
+  }
+
+  // ie link detection, as adapted from 
https://github.com/cujojs/curl/blob/master/src/curl/plugin/css.js
+  if (engine == 'trident' && hackLinks) {
+    var ieStyles = [],
+      ieQueue = [],
+      ieStyleCnt = 0;
+    var ieLoad = function(url, callback) {
+      var style;
+      ieQueue.push({
+        url: url,
+        cb: callback
+      });
+      style = ieStyles.shift();
+      if (!style && ieStyleCnt++ < 12) {
+        style = document.createElement('style');
+        head.appendChild(style);
+      }
+      ieLoadNextImport(style);
+    }
+    var ieLoadNextImport = function(style) {
+      var curImport = ieQueue.shift();
+      if (!curImport) {
+        style.onload = noop;
+        ieStyles.push(style);
+        return;  
+      }
+      style.onload = function() {
+        curImport.cb(curImport.ss);
+        ieLoadNextImport(style);
+      };
+      var curSheet = style.styleSheet;
+      curImport.ss = curSheet.imports[curSheet.addImport(curImport.url)];
+    }
+  }
+
+  // uses the <link> load method
+  var createLink = function(url) {
+    var link = document.createElement('link');
+    link.type = 'text/css';
+    link.rel = 'stylesheet';
+    link.href = url;
+    return link;
+  }
+
+  var noop = function(){}
+
+  cssAPI.linkLoad = function(url, callback) {
+    var timeout = setTimeout(function() {
+      if (testing) alert('timeout');
+      callback();
+    }, waitSeconds * 1000 - 100);
+    var _callback = function() {
+      clearTimeout(timeout);
+      if (link)
+        link.onload = noop;
+      // for style querying, a short delay still seems necessary
+      setTimeout(callback, 7);
+    }
+    if (!hackLinks) {
+      var link = createLink(url);
+      link.onload = _callback;
+      head.appendChild(link);
+    }
+    // hacks
+    else {
+      if (engine == 'webkit') {
+        var link = createLink(url);
+        webkitLoadCheck(link, _callback);
+        head.appendChild(link);
+      }
+      else if (engine == 'gecko') {
+        var style = document.createElement('style');
+        style.textContent = '@import "' + url + '"';
+        mozillaLoadCheck(style, _callback);
+        head.appendChild(style);
+      }
+      else if (engine == 'trident')
+        ieLoad(url, _callback);
+    }
+  }
+
+  /* injection api */
+  var progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'];
+  var fileCache = {};
+  var get = function(url, callback, errback) {
+    if (fileCache[url]) {
+      callback(fileCache[url]);
+      return;
+    }
+
+    var xhr, i, progId;
+    if (typeof XMLHttpRequest !== 'undefined')
+      xhr = new XMLHttpRequest();
+    else if (typeof ActiveXObject !== 'undefined')
+      for (i = 0; i < 3; i += 1) {
+        progId = progIds[i];
+        try {
+          xhr = new ActiveXObject(progId);
+        }
+        catch (e) {}
+  
+        if (xhr) {
+          progIds = [progId];  // so faster next time
+          break;
+        }
+      }
+    
+    xhr.open('GET', url, requirejs.inlineRequire ? false : true);
+  
+    xhr.onreadystatechange = function (evt) {
+      var status, err;
+      //Do not explicitly handle errors, those should be
+      //visible via console output in the browser.
+      if (xhr.readyState === 4) {
+        status = xhr.status;
+        if (status > 399 && status < 600) {
+          //An http 4xx or 5xx error. Signal an error.
+          err = new Error(url + ' HTTP status: ' + status);
+          err.xhr = xhr;
+          errback(err);
+        }
+        else {
+          fileCache[url] = xhr.responseText;
+          callback(xhr.responseText);
+        }
+      }
+    };
+    
+    xhr.send(null);
+  }
+  //uses the <style> load method
+  var styleCnt = 0;
+  var curStyle;
+  cssAPI.inject = function(css) {
+    if (styleCnt < 31) {
+      curStyle = document.createElement('style');
+      curStyle.type = 'text/css';
+      head.appendChild(curStyle);
+      styleCnt++;
+    }
+    if (curStyle.styleSheet)
+      curStyle.styleSheet.cssText += css;
+    else
+      curStyle.appendChild(document.createTextNode(css));
+  }
+  
+  // NB add @media query support for media imports
+  var importRegEx = 
/@import\s*(url)?\s*(('([^']*)'|"([^"]*)")|\(('([^']*)'|"([^"]*)"|([^\)]*))\))\s*;?/g;
+
+  var pathname = window.location.pathname.split('/');
+  pathname.pop();
+  pathname = pathname.join('/') + '/';
+
+  var loadCSS = function(fileUrl, callback, errback) {
+
+    //make file url absolute
+    if (!fileUrl.match(absUrlRegEx))
+      fileUrl = '/' + normalize.convertURIBase(fileUrl, pathname, '/');
+
+    get(fileUrl, function(css) {
+
+      // normalize the css (except import statements)
+      css = normalize(css, fileUrl, pathname);
+
+      // detect all import statements in the css and normalize
+      var importUrls = [];
+      var importIndex = [];
+      var importLength = [];
+      var match;
+      while (match = importRegEx.exec(css)) {
+        var importUrl = match[4] || match[5] || match[7] || match[8] || 
match[9];
+
+        importUrls.push(importUrl);
+        importIndex.push(importRegEx.lastIndex - match[0].length);
+        importLength.push(match[0].length);
+      }
+
+      // load the import stylesheets and substitute into the css
+      var completeCnt = 0;
+      for (var i = 0; i < importUrls.length; i++)
+        (function(i) {
+          loadCSS(importUrls[i], function(importCSS) {
+            css = css.substr(0, importIndex[i]) + importCSS + 
css.substr(importIndex[i] + importLength[i]);
+            var lenDiff = importCSS.length - importLength[i];
+            for (var j = i + 1; j < importUrls.length; j++)
+              importIndex[j] += lenDiff;
+            completeCnt++;
+            if (completeCnt == importUrls.length) {
+              callback(css);
+            }
+          }, errback);
+        })(i);
+
+      if (importUrls.length == 0)
+        callback(css);
+    }, errback);
+  }
+
+  
+  cssAPI.normalize = function(name, normalize) {
+    if (name.substr(name.length - 4, 4) == '.css')
+      name = name.substr(0, name.length - 4);
+    
+    return normalize(name);
+  }
+  
+  var waitSeconds;
+  var alerted = false;
+  cssAPI.load = function(cssId, req, load, config, parse) {
+    
+    waitSeconds = waitSeconds || config.waitSeconds || 7;
+
+    var resourceId = cssId + (!parse ? '.css' : '.less');
+
+    // attach the load function to a buffer if there is one in registration
+    // if not, we do a full injection load
+    if (cssAPI.attachBuffer(resourceId, load))
+      return;
+
+    fileUrl = req.toUrl(resourceId);
+    
+    if (!alerted && testing) {
+      alert(hackLinks ? 'hacking links' : 'not hacking');
+      alerted = true;
+    }
+
+    if (!parse) {
+      cssAPI.linkLoad(fileUrl, load);
+    }
+    else {
+      loadCSS(fileUrl, function(css) {
+        // run parsing after normalization - since less is a CSS subset this 
works fine
+        if (parse)
+          css = parse(css, function(css) {
+            cssAPI.inject(css);
+            setTimeout(load, 7);
+          });
+      });
+    }
+  }
+
+  if (testing)
+    cssAPI.inspect = function() {
+      if (stylesheet.styleSheet)
+        return stylesheet.styleSheet.cssText;
+      else if (stylesheet.innerHTML)
+        return stylesheet.innerHTML;
+    }
+  
+  return cssAPI;
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2bf0c765/src/fauxton/assets/js/plugins/require-css/example/build.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/plugins/require-css/example/build.js 
b/src/fauxton/assets/js/plugins/require-css/example/build.js
new file mode 100644
index 0000000..1dba1dc
--- /dev/null
+++ b/src/fauxton/assets/js/plugins/require-css/example/build.js
@@ -0,0 +1,31 @@
+({
+  appDir: 'www',
+  dir: 'www-built',
+  baseUrl: '.',
+  fileExclusionRegExp: /(^example)|(.git)$/,
+  //separateCSS: true,
+  optimizeCss: "node",
+  map: {
+    '*': {
+      css: 'require-css/css'
+    }
+  },
+  modules: [
+  {
+    name: 'app',
+    exclude: ['core-components'],
+  },
+  {
+    name: 'core-components',
+    separateCSS: true,
+    create: true,
+    include: ['components/component'], 
+  },
+  {
+    name: 'popup',
+    exclude: ['core-components']
+  }
+  ]
+  //name: 'app.js',
+  //out: 'app-built.js'
+})

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2bf0c765/src/fauxton/assets/js/plugins/require-css/example/setup.sh
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/plugins/require-css/example/setup.sh 
b/src/fauxton/assets/js/plugins/require-css/example/setup.sh
new file mode 100755
index 0000000..8d188ab
--- /dev/null
+++ b/src/fauxton/assets/js/plugins/require-css/example/setup.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+# build the symlink to require-css. done by script as it breaks project builds
+cd www
+ln -s ../../ require-css

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2bf0c765/src/fauxton/assets/js/plugins/require-css/example/test.html
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/plugins/require-css/example/test.html 
b/src/fauxton/assets/js/plugins/require-css/example/test.html
new file mode 100644
index 0000000..dcb38d1
--- /dev/null
+++ b/src/fauxton/assets/js/plugins/require-css/example/test.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<html>
+<script type='text/javascript' src='../../../require.js'></script>
+<script>
+  require.config({
+    baseUrl: 
'/Users/guybedford/Projects/OpenClient/www/lib/require-css/example/www-built/',
+    map: {
+      '*': {
+        'css': 'require-css/css'
+      } 
+    }
+  });
+</script>
+<link rel='stylesheet' href='core-components.css'></link>
+<script src='core-components.js'></script>
+
+<body>
+<h1>test</h1>
+</body>
+
+
+<script>
+  require(['app'], function(){});
+  require(['popup'], function(popupHTML) {
+    var div = document.createElement('div');
+    div.innerHTML = popupHTML;
+    document.body.appendChild(div);
+    alert(div.childNodes[0].offsetWidth == 340 ? 'Style query passed' : 'Style 
query failed');
+  });
+</script>

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2bf0c765/src/fauxton/assets/js/plugins/require-css/example/www/app.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/plugins/require-css/example/www/app.js 
b/src/fauxton/assets/js/plugins/require-css/example/www/app.js
new file mode 100755
index 0000000..31b28c1
--- /dev/null
+++ b/src/fauxton/assets/js/plugins/require-css/example/www/app.js
@@ -0,0 +1,4 @@
+/* nb css form below implies inline style in js file for automatic injection */
+define(['css!style/style', 'components/component'], function(component) {
+  return 'uses the component!';
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2bf0c765/src/fauxton/assets/js/plugins/require-css/example/www/components/component.css
----------------------------------------------------------------------
diff --git 
a/src/fauxton/assets/js/plugins/require-css/example/www/components/component.css
 
b/src/fauxton/assets/js/plugins/require-css/example/www/components/component.css
new file mode 100755
index 0000000..cc67e7c
--- /dev/null
+++ 
b/src/fauxton/assets/js/plugins/require-css/example/www/components/component.css
@@ -0,0 +1,5 @@
+/* component.css */
+@import 'test.css';
+body {
+  background-image: url(../test.jpg);
+}

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2bf0c765/src/fauxton/assets/js/plugins/require-css/example/www/components/component.js
----------------------------------------------------------------------
diff --git 
a/src/fauxton/assets/js/plugins/require-css/example/www/components/component.js 
b/src/fauxton/assets/js/plugins/require-css/example/www/components/component.js
new file mode 100755
index 0000000..0e45eae
--- /dev/null
+++ 
b/src/fauxton/assets/js/plugins/require-css/example/www/components/component.js
@@ -0,0 +1,3 @@
+define(['css!./component'], function() {
+  return {component: 'is here'};
+});

http://git-wip-us.apache.org/repos/asf/couchdb/blob/2bf0c765/src/fauxton/assets/js/plugins/require-css/example/www/components/test.css
----------------------------------------------------------------------
diff --git 
a/src/fauxton/assets/js/plugins/require-css/example/www/components/test.css 
b/src/fauxton/assets/js/plugins/require-css/example/www/components/test.css
new file mode 100644
index 0000000..4d92b31
--- /dev/null
+++ b/src/fauxton/assets/js/plugins/require-css/example/www/components/test.css
@@ -0,0 +1,3 @@
+body {
+  border: 1px solid #555;
+}

Reply via email to