You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by yo...@apache.org on 2012/02/16 01:12:13 UTC

svn commit: r1244800 [1/2] - in /incubator/cordova/site: ./ bin/ lib/ lib/mustache/ public/ public/images/ public/js/ www/ www/images/ www/js/

Author: yohei
Date: Thu Feb 16 00:12:11 2012
New Revision: 1244800

URL: http://svn.apache.org/viewvc?rev=1244800&view=rev
Log:
Added cordova site

Added:
    incubator/cordova/site/
    incubator/cordova/site/README.md
    incubator/cordova/site/bin/
    incubator/cordova/site/bin/config.json
    incubator/cordova/site/bin/gen.rb
    incubator/cordova/site/lib/
    incubator/cordova/site/lib/mustache/
    incubator/cordova/site/lib/mustache.rb   (with props)
    incubator/cordova/site/lib/mustache/context.rb   (with props)
    incubator/cordova/site/lib/mustache/generator.rb   (with props)
    incubator/cordova/site/lib/mustache/parser.rb   (with props)
    incubator/cordova/site/lib/mustache/settings.rb   (with props)
    incubator/cordova/site/lib/mustache/sinatra.rb   (with props)
    incubator/cordova/site/lib/mustache/template.rb   (with props)
    incubator/cordova/site/lib/mustache/version.rb   (with props)
    incubator/cordova/site/public/
    incubator/cordova/site/public/images/
    incubator/cordova/site/public/images/cordova_bot.jpg   (with props)
    incubator/cordova/site/public/images/grid.png   (with props)
    incubator/cordova/site/public/images/shadow.png   (with props)
    incubator/cordova/site/public/images/sprite.png   (with props)
    incubator/cordova/site/public/index.html
    incubator/cordova/site/public/js/
    incubator/cordova/site/public/js/smooth.pack.js   (with props)
    incubator/cordova/site/public/master.css
    incubator/cordova/site/www/
    incubator/cordova/site/www/images/
    incubator/cordova/site/www/images/cordova_bot.jpg   (with props)
    incubator/cordova/site/www/images/grid.png   (with props)
    incubator/cordova/site/www/images/shadow.png   (with props)
    incubator/cordova/site/www/images/sprite.png   (with props)
    incubator/cordova/site/www/js/
    incubator/cordova/site/www/js/less-1.1.5.min.js
    incubator/cordova/site/www/js/smooth.pack.js   (with props)
    incubator/cordova/site/www/master.less
    incubator/cordova/site/www/template.html

Added: incubator/cordova/site/README.md
URL: http://svn.apache.org/viewvc/incubator/cordova/site/README.md?rev=1244800&view=auto
==============================================================================
--- incubator/cordova/site/README.md (added)
+++ incubator/cordova/site/README.md Thu Feb 16 00:12:11 2012
@@ -0,0 +1,26 @@
+Cordova Website
+==========================
+
+
+Dependencies
+-----------------------
+
+- Mustache for Ruby
+- LessCSS
+- Json
+
+
+How to compile the site
+-----------------------
+
+- from commandline, set `cd` to your `cordova-website` repo
+- run the command: `ruby bin/gen.rb`
+- the site will be generated in `public` folder
+
+
+Things you should know
+-----------------------
+
+- `bin/config.json` + `www/template.html` + Mustache outputs `index.html`
+- `bin/config.json` contains information for: download & archives, quick links, and list of repos
+- the site can be tested by running `www` locally. This is handy for modifying css

Added: incubator/cordova/site/bin/config.json
URL: http://svn.apache.org/viewvc/incubator/cordova/site/bin/config.json?rev=1244800&view=auto
==============================================================================
--- incubator/cordova/site/bin/config.json (added)
+++ incubator/cordova/site/bin/config.json Thu Feb 16 00:12:11 2012
@@ -0,0 +1,89 @@
+{
+	"releases":[
+		/*{
+			"version": 	"1.4",
+			"file": 	"#",
+			"note": 	"#"
+		}*/
+	],
+	
+	"repos":{
+		"platforms":[
+			{
+				"name": 	"Android",
+				"github": 	"https://github.com/apache/incubator-cordova-android",
+				"apache": 	"https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-android.git;a=summary"
+			},
+			{
+				"name": 	"Bada",
+				"github": 	"https://github.com/apache/incubator-cordova-bada",
+				"apache": 	"https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-bada.git;a=summary"
+			},
+			{
+				"name": 	"Blackberry",
+				"github": 	"https://github.com/apache/incubator-cordova-blackberry-webworks",
+				"apache": 	"https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-blackberry-webworks.git;a=summary"
+			},
+			{
+				"name": 	"iOS",
+				"github": 	"https://github.com/apache/incubator-cordova-ios",
+				"apache": 	"https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-ios.git;a=summary"
+			},
+			{
+				"name": 	"Mac OS X",
+				"github": 	"https://github.com/apache/incubator-cordova-mac",
+				"apache": 	"https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-mac.git;a=summary"
+			},
+			{
+				"name": 	"WebOS",
+				"github": 	"https://github.com/apache/incubator-cordova-webos",
+				"apache": 	"https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-webos.git;a=summary"
+			},
+			{
+				"name": 	"Windows Phone",
+				"github": 	"https://github.com/apache/incubator-cordova-wp7",
+				"apache": 	"https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-wp7.git;a=summary"
+			}
+		],
+		
+		"other":[
+			{
+				"name": 	"Docs",
+				"github": 	"https://github.com/apache/incubator-cordova-docs",
+				"apache": 	"https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-docs.git;a=summary"
+			},
+			{
+				"name": 	"Mobile Spec",
+				"github": 	"https://github.com/apache/incubator-cordova-mobile-spec",
+				"apache": 	"https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-mobile-spec.git;a=summary"
+			},
+			{
+				"name": 	"Weinre",
+				"github": 	"https://github.com/apache/incubator-cordova-weinre",
+				"apache": 	"https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-weinre.git;a=summary"
+			}
+		]
+	},
+	
+	"sitemap":{
+		"general":[
+			{ "title":"About Cordova",  "url":"#about" },
+			{ "title":"Incubator Page", "url":"http://incubator.apache.org/projects/callback.html" },
+			{ "title":"License",        "url":"http://www.apache.org/licenses/LICENSE-2.0" }
+		],
+		"dev":[
+			{ "title":"Download",      "url":"#download" },
+			{ "title":"Source Code",   "url":"https://git-wip-us.apache.org/repos/asf" },
+			{ "title":"License",       "url":"http://www.apache.org/licenses/LICENSE-2.0" },
+			{ "title":"Mailing List",  "url":"#mailing-list" },
+			{ "title":"Issue Tracker", "url":"https://issues.apache.org/jira/browse/CB" },
+			{ "title":"Wiki",          "url":"http://wiki.apache.org/cordova/" }
+		],
+		"asf":[
+			{ "title":"About ASF",        "url":"http://www.apache.org/" },
+			{ "title":"Thanks",           "url":"http://www.apache.org/foundation/thanks.html" },
+			{ "title":"Become a Sponsor", "url":"http://www.apache.org/foundation/sponsorship.html" },
+			{ "title":"Security",         "url":"http://www.apache.org/security/" }
+		]
+	}
+}
\ No newline at end of file

Added: incubator/cordova/site/bin/gen.rb
URL: http://svn.apache.org/viewvc/incubator/cordova/site/bin/gen.rb?rev=1244800&view=auto
==============================================================================
--- incubator/cordova/site/bin/gen.rb (added)
+++ incubator/cordova/site/bin/gen.rb Thu Feb 16 00:12:11 2012
@@ -0,0 +1,73 @@
+$LOAD_PATH.unshift File.dirname( __FILE__ ) + '/../lib'
+require 'mustache'
+require 'rubygems'
+require 'json'
+require 'ftools'
+require 'Fileutils.rb'
+
+# preparation for mustache
+Mustache.template_file = File.dirname( __FILE__ ) + '/../www/template.html'
+view = Mustache.new
+json_file = File.dirname( __FILE__ ) + '/config.json';
+data = JSON.parse( IO.read( json_file ) )
+
+# download button and archives
+releases = data['releases']
+if releases.length > 0
+    latest_item = releases[0]
+    archives = releases.slice(1, releases.length)
+    len = archives.length;
+    column_len = ( len / 3.0 ).ceil
+    view[:download_set1] = archives.slice( 0, column_len )
+    view[:download_set2] = archives.slice( column_len, column_len )
+    view[:download_set3] = archives.slice( column_len*2, column_len )
+    view[:latest_version] = latest_item['version']
+    view[:download_link] = latest_item['file']
+    view[:hide_archives] = len == 0
+else
+    view[:hide_archives] = true
+    view[:no_download] = true
+end
+
+# list of repos
+repos = data['repos']
+view[:repo_platforms] = repos['platforms']
+view[:repo_platforms][0]['first'] = true
+view[:repo_other] = repos['other']
+view[:repo_other][0]['first'] = true
+
+# quicklinks / sitemap
+sitemap = data['sitemap']
+view[:links_general] = sitemap['general']
+view[:links_dev] = sitemap['dev']
+view[:links_asf] = sitemap['asf']
+
+# preparing to generate site
+tmp_directory = 'tmp'
+Dir.mkdir( tmp_directory ) unless File.exists?( tmp_directory )
+
+# copying files from www
+files = Dir.glob( 'www/*' )
+FileUtils.cp_r( files, tmp_directory )
+
+# generating index.html
+File.open( tmp_directory + '/index.html', 'w' ) do | file | 
+    file_data = view.render( data )
+    file_data = file_data.gsub( /(\r|\n)<\![\s-]{0,5}localstart[^*]+?localend[\s-]{0,5}>|<!--\spublicstart[^<]+|\spublicend[^*]+?-->/, '' )
+    file.puts view.render( file_data )
+end
+
+# LessCSS
+system( "lessc www/master.less > " + tmp_directory + "/master.css" )
+
+# remove unnecessary files
+delete_files = ['/template.html', '/js/local.js', '/js/less-1.1.5.min.js', '/master.less']
+for i in delete_files
+    File.delete( tmp_directory+i ) unless !File.exists?( tmp_directory+i )
+end
+
+# rename tmp folder to public
+p_files = Dir.glob( 'public/*' )
+FileUtils.rm_rf( p_files ) unless !File.exists?( tmp_directory )
+File.rename( tmp_directory, 'public' )
+

Added: incubator/cordova/site/lib/mustache.rb
URL: http://svn.apache.org/viewvc/incubator/cordova/site/lib/mustache.rb?rev=1244800&view=auto
==============================================================================
--- incubator/cordova/site/lib/mustache.rb (added)
+++ incubator/cordova/site/lib/mustache.rb Thu Feb 16 00:12:11 2012
@@ -0,0 +1,304 @@
+require 'mustache/template'
+require 'mustache/context'
+require 'mustache/settings'
+
+# Mustache is the base class from which your Mustache subclasses
+# should inherit (though it can be used on its own).
+#
+# The typical Mustache workflow is as follows:
+#
+# * Create a Mustache subclass: class Stats < Mustache
+# * Create a template: stats.mustache
+# * Instantiate an instance: view = Stats.new
+# * Render that instance: view.render
+#
+# You can skip the instantiation by calling `Stats.render` directly.
+#
+# While Mustache will do its best to load and render a template for
+# you, this process is completely customizable using a few options.
+#
+# All settings can be overriden at the class level.
+#
+# For example, going with the above example, we can use
+# `Stats.template_path = "/usr/local/templates"` to specify the path
+# Mustache uses to find templates.
+#
+# Here are the available options:
+#
+# * template_path
+#
+# The `template_path` setting determines the path Mustache uses when
+# looking for a template. By default it is "."
+# Setting it to /usr/local/templates, for example, means (given all
+# other settings are default) a Mustache subclass `Stats` will try to
+# load /usr/local/templates/stats.mustache
+#
+# * template_extension
+#
+# The `template_extension` is the extension Mustache uses when looking
+# for template files. By default it is "mustache"
+#
+# * template_file
+#
+# You can tell Mustache exactly which template to use with this
+# setting. It can be a relative or absolute path.
+#
+# * template
+#
+# Sometimes you want Mustache to render a string, not a file. In those
+# cases you may set the `template` setting. For example:
+#
+#   >> Mustache.render("Hello {{planet}}", :planet => "World!")
+#   => "Hello World!"
+#
+# The `template` setting is also available on instances.
+#
+#   view = Mustache.new
+#   view.template = "Hi, {{person}}!"
+#   view[:person] = 'Mom'
+#   view.render # => Hi, mom!
+#
+# * view_namespace
+#
+# To make life easy on those developing Mustache plugins for web frameworks or
+# other libraries, Mustache will attempt to load view classes (i.e. Mustache
+# subclasses) using the `view_class` class method. The `view_namespace` tells
+# Mustache under which constant view classes live. By default it is `Object`.
+#
+# * view_path
+#
+# Similar to `template_path`, the `view_path` option tells Mustache where to look
+# for files containing view classes when using the `view_class` method.
+#
+class Mustache
+
+  #
+  # Public API
+  #
+
+  # Instantiates an instance of this class and calls `render` with
+  # the passed args.
+  #
+  # Returns a rendered String version of a template
+  def self.render(*args)
+    new.render(*args)
+  end
+
+  class << self
+    alias_method :to_html, :render
+    alias_method :to_text, :render
+  end
+
+  # Parses our fancy pants template file and returns normal file with
+  # all special {{tags}} and {{#sections}}replaced{{/sections}}.
+  #
+  # data - A String template or a Hash context. If a Hash is given,
+  #        we'll try to figure out the template from the class.
+  #  ctx - A Hash context if `data` is a String template.
+  #
+  # Examples
+  #
+  #   @view.render("Hi {{thing}}!", :thing => :world)
+  #
+  #   View.template = "Hi {{thing}}!"
+  #   @view = View.new
+  #   @view.render(:thing => :world)
+  #
+  # Returns a rendered String version of a template
+  def render(data = template, ctx = {})
+    if data.is_a? Hash
+      ctx = data
+      tpl = templateify(template)
+    elsif data.is_a? Symbol
+      self.template_name = data
+      tpl = templateify(template)
+    else
+      tpl = templateify(data)
+    end
+
+    return tpl.render(context) if ctx == {}
+
+    begin
+      context.push(ctx)
+      tpl.render(context)
+    ensure
+      context.pop
+    end
+  end
+
+  alias_method :to_html, :render
+  alias_method :to_text, :render
+
+  # Context accessors.
+  #
+  # view = Mustache.new
+  # view[:name] = "Jon"
+  # view.template = "Hi, {{name}}!"
+  # view.render # => "Hi, Jon!"
+  def [](key)
+    context[key.to_sym]
+  end
+
+  def []=(key, value)
+    context[key.to_sym] = value
+  end
+
+  # A helper method which gives access to the context at a given time.
+  # Kind of a hack for now, but useful when you're in an iterating section
+  # and want access to the hash currently being iterated over.
+  def context
+    @context ||= Context.new(self)
+  end
+
+  # Given a file name and an optional context, attempts to load and
+  # render the file as a template.
+  def self.render_file(name, context = {})
+    render(partial(name), context)
+  end
+
+  # Given a file name and an optional context, attempts to load and
+  # render the file as a template.
+  def render_file(name, context = {})
+    self.class.render_file(name, context)
+  end
+
+  # Given a name, attempts to read a file and return the contents as a
+  # string. The file is not rendered, so it might contain
+  # {{mustaches}}.
+  #
+  # Call `render` if you need to process it.
+  def self.partial(name)
+    File.read("#{template_path}/#{name}.#{template_extension}")
+  end
+
+  # Override this in your subclass if you want to do fun things like
+  # reading templates from a database. It will be rendered by the
+  # context, so all you need to do is return a string.
+  def partial(name)
+    self.class.partial(name)
+  end
+
+  # Override this to provide custom escaping.
+  #
+  # class PersonView < Mustache
+  #   def escapeHTML(str)
+  #     my_html_escape_method(str)
+  #   end
+  # end
+  #
+  # Returns a String
+  def escapeHTML(str)
+    CGI.escapeHTML(str)
+  end
+
+
+  #
+  # Private API
+  #
+
+  # When given a symbol or string representing a class, will try to produce an
+  # appropriate view class.
+  # e.g.
+  #   Mustache.view_namespace = Hurl::Views
+  #   Mustache.view_class(:Partial) # => Hurl::Views::Partial
+  def self.view_class(name)
+    if name != classify(name.to_s)
+      name = classify(name.to_s)
+    end
+
+    # Emptiness begets emptiness.
+    if name.to_s == ''
+      return Mustache
+    end
+
+    file_name = underscore(name)
+    name = "#{view_namespace}::#{name}"
+
+    if const = const_get!(name)
+      const
+    elsif File.exists?(file = "#{view_path}/#{file_name}.rb")
+      require "#{file}".chomp('.rb')
+      const_get!(name) || Mustache
+    else
+      Mustache
+    end
+  end
+
+  # Supercharged version of Module#const_get.
+  #
+  # Always searches under Object and can find constants by their full name,
+  #   e.g. Mustache::Views::Index
+  #
+  # name - The full constant name to find.
+  #
+  # Returns the constant if found
+  # Returns nil if nothing is found
+  def self.const_get!(name)
+    name.split('::').inject(Object) do |klass, cname|
+      klass.const_get(cname)
+    end
+  rescue NameError
+    nil
+  end
+
+  # Has this template already been compiled? Compilation is somewhat
+  # expensive so it may be useful to check this before attempting it.
+  def self.compiled?
+    @template.is_a? Template
+  end
+
+  # Has this instance or its class already compiled a template?
+  def compiled?
+    (@template && @template.is_a?(Template)) || self.class.compiled?
+  end
+
+  # template_partial => TemplatePartial
+  # template/partial => Template::Partial
+  def self.classify(underscored)
+    underscored.split('/').map do |namespace|
+      namespace.split(/[-_]/).map do |part|
+        part[0] = part[0].chr.upcase; part
+      end.join
+    end.join('::')
+  end
+
+  #   TemplatePartial => template_partial
+  # Template::Partial => template/partial
+  # Takes a string but defaults to using the current class' name.
+  def self.underscore(classified = name)
+    classified = name if classified.to_s.empty?
+    classified = superclass.name if classified.to_s.empty?
+
+    string = classified.dup.split("#{view_namespace}::").last
+
+    string.split('::').map do |part|
+      part[0] = part[0].chr.downcase
+      part.gsub(/[A-Z]/) { |s| "_#{s.downcase}"}
+    end.join('/')
+  end
+
+  # Turns a string into a Mustache::Template. If passed a Template,
+  # returns it.
+  def self.templateify(obj)
+    if obj.is_a?(Template)
+      obj
+    else
+      Template.new(obj.to_s)
+    end
+  end
+
+  def templateify(obj)
+    self.class.templateify(obj)
+  end
+
+  # Return the value of the configuration setting on the superclass, or return
+  # the default.
+  #
+  # attr_name - Symbol name of the attribute.  It should match the instance variable.
+  # default   - Default value to use if the superclass does not respond.
+  #
+  # Returns the inherited or default configuration setting.
+  def self.inheritable_config_for(attr_name, default)
+    superclass.respond_to?(attr_name) ? superclass.send(attr_name) : default
+  end
+end

Propchange: incubator/cordova/site/lib/mustache.rb
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/cordova/site/lib/mustache/context.rb
URL: http://svn.apache.org/viewvc/incubator/cordova/site/lib/mustache/context.rb?rev=1244800&view=auto
==============================================================================
--- incubator/cordova/site/lib/mustache/context.rb (added)
+++ incubator/cordova/site/lib/mustache/context.rb Thu Feb 16 00:12:11 2012
@@ -0,0 +1,142 @@
+class Mustache
+  # A ContextMiss is raised whenever a tag's target can not be found
+  # in the current context if `Mustache#raise_on_context_miss?` is
+  # set to true.
+  #
+  # For example, if your View class does not respond to `music` but
+  # your template contains a `{{music}}` tag this exception will be raised.
+  #
+  # By default it is not raised. See Mustache.raise_on_context_miss.
+  class ContextMiss < RuntimeError;  end
+
+  # A Context represents the context which a Mustache template is
+  # executed within. All Mustache tags reference keys in the Context.
+  class Context
+    # Expect to be passed an instance of `Mustache`.
+    def initialize(mustache)
+      @stack = [mustache]
+    end
+
+    # A {{>partial}} tag translates into a call to the context's
+    # `partial` method, which would be this sucker right here.
+    #
+    # If the Mustache view handling the rendering (e.g. the view
+    # representing your profile page or some other template) responds
+    # to `partial`, we call it and render the result.
+    def partial(name, indentation = '')
+      # Look for the first Mustache in the stack.
+      mustache = mustache_in_stack
+
+      # Indent the partial template by the given indentation.
+      part = mustache.partial(name).to_s.gsub(/^/, indentation)
+
+      # Call the Mustache's `partial` method and render the result.
+      result = mustache.render(part, self)
+    end
+
+    # Find the first Mustache in the stack. If we're being rendered
+    # inside a Mustache object as a context, we'll use that one.
+    def mustache_in_stack
+      @stack.detect { |frame| frame.is_a?(Mustache) }
+    end
+
+    # Allows customization of how Mustache escapes things.
+    #
+    # Returns a String.
+    def escapeHTML(str)
+      mustache_in_stack.escapeHTML(str)
+    end
+
+    # Adds a new object to the context's internal stack.
+    #
+    # Returns the Context.
+    def push(new)
+      @stack.unshift(new)
+      self
+    end
+    alias_method :update, :push
+
+    # Removes the most recently added object from the context's
+    # internal stack.
+    #
+    # Returns the Context.
+    def pop
+      @stack.shift
+      self
+    end
+
+    # Can be used to add a value to the context in a hash-like way.
+    #
+    # context[:name] = "Chris"
+    def []=(name, value)
+      push(name => value)
+    end
+
+    # Alias for `fetch`.
+    def [](name)
+      fetch(name, nil)
+    end
+
+    # Do we know about a particular key? In other words, will calling
+    # `context[key]` give us a result that was set. Basically.
+    def has_key?(key)
+      !!fetch(key)
+    rescue ContextMiss
+      false
+    end
+
+    # Similar to Hash#fetch, finds a value by `name` in the context's
+    # stack. You may specify the default return value by passing a
+    # second parameter.
+    #
+    # If no second parameter is passed (or raise_on_context_miss is
+    # set to true), will raise a ContextMiss exception on miss.
+    def fetch(name, default = :__raise)
+      @stack.each do |frame|
+        # Prevent infinite recursion.
+        next if frame == self
+
+        value = find(frame, name, :__missing)
+        if value != :__missing
+          return value
+        end
+      end
+
+      if default == :__raise || mustache_in_stack.raise_on_context_miss?
+        raise ContextMiss.new("Can't find #{name} in #{@stack.inspect}")
+      else
+        default
+      end
+    end
+
+    # Finds a key in an object, using whatever method is most
+    # appropriate. If the object is a hash, does a simple hash lookup.
+    # If it's an object that responds to the key as a method call,
+    # invokes that method. You get the idea.
+    #
+    #     obj - The object to perform the lookup on.
+    #     key - The key whose value you want.
+    # default - An optional default value, to return if the
+    #           key is not found.
+    #
+    # Returns the value of key in obj if it is found and default otherwise.
+    def find(obj, key, default = nil)
+      hash = obj.respond_to?(:has_key?)
+
+      if hash && obj.has_key?(key)
+        obj[key]
+      elsif hash && obj.has_key?(key.to_s)
+        obj[key.to_s]
+      elsif !hash && obj.respond_to?(key)
+        meth = obj.method(key) rescue proc { obj.send(key) }
+        if meth.arity == 1
+          meth.to_proc
+        else
+          meth[]
+        end
+      else
+        default
+      end
+    end
+  end
+end

Propchange: incubator/cordova/site/lib/mustache/context.rb
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/cordova/site/lib/mustache/generator.rb
URL: http://svn.apache.org/viewvc/incubator/cordova/site/lib/mustache/generator.rb?rev=1244800&view=auto
==============================================================================
--- incubator/cordova/site/lib/mustache/generator.rb (added)
+++ incubator/cordova/site/lib/mustache/generator.rb Thu Feb 16 00:12:11 2012
@@ -0,0 +1,195 @@
+class Mustache
+  # The Generator is in charge of taking an array of Mustache tokens,
+  # usually assembled by the Parser, and generating an interpolatable
+  # Ruby string. This string is considered the "compiled" template
+  # because at that point we're relying on Ruby to do the parsing and
+  # run our code.
+  #
+  # For example, let's take this template:
+  #
+  #   Hi {{thing}}!
+  #
+  # If we run this through the Parser we'll get these tokens:
+  #
+  #   [:multi,
+  #     [:static, "Hi "],
+  #     [:mustache, :etag, "thing"],
+  #     [:static, "!\n"]]
+  #
+  # Now let's hand that to the Generator:
+  #
+  # >> puts Mustache::Generator.new.compile(tokens)
+  # "Hi #{CGI.escapeHTML(ctx[:thing].to_s)}!\n"
+  #
+  # You can see the generated Ruby string for any template with the
+  # mustache(1) command line tool:
+  #
+  #   $ mustache --compile test.mustache
+  #   "Hi #{CGI.escapeHTML(ctx[:thing].to_s)}!\n"
+  class Generator
+    # Options are unused for now but may become useful in the future.
+    def initialize(options = {})
+      @options = options
+    end
+
+    # Given an array of tokens, returns an interpolatable Ruby string.
+    def compile(exp)
+      "\"#{compile!(exp)}\""
+    end
+
+    # Given an array of tokens, converts them into Ruby code. In
+    # particular there are three types of expressions we are concerned
+    # with:
+    #
+    #   :multi
+    #     Mixed bag of :static, :mustache, and whatever.
+    #
+    #   :static
+    #     Normal HTML, the stuff outside of {{mustaches}}.
+    #
+    #   :mustache
+    #     Any Mustache tag, from sections to partials.
+    #
+    # To give you an idea of what you'll be dealing with take this
+    # template:
+    #
+    #   Hello {{name}}
+    #   You have just won ${{value}}!
+    #   {{#in_ca}}
+    #   Well, ${{taxed_value}}, after taxes.
+    #   {{/in_ca}}
+    #
+    # If we run this through the Parser, we'll get back this array of
+    # tokens:
+    #
+    #   [:multi,
+    #    [:static, "Hello "],
+    #    [:mustache, :etag, "name"],
+    #    [:static, "\nYou have just won $"],
+    #    [:mustache, :etag, "value"],
+    #    [:static, "!\n"],
+    #    [:mustache,
+    #     :section,
+    #     "in_ca",
+    #     [:multi,
+    #      [:static, "Well, $"],
+    #      [:mustache, :etag, "taxed_value"],
+    #      [:static, ", after taxes.\n"]]]]
+    def compile!(exp)
+      case exp.first
+      when :multi
+        exp[1..-1].map { |e| compile!(e) }.join
+      when :static
+        str(exp[1])
+      when :mustache
+        send("on_#{exp[1]}", *exp[2..-1])
+      else
+        raise "Unhandled exp: #{exp.first}"
+      end
+    end
+
+    # Callback fired when the compiler finds a section token. We're
+    # passed the section name and the array of tokens.
+    def on_section(name, content, raw, delims)
+      # Convert the tokenized content of this section into a Ruby
+      # string we can use.
+      code = compile(content)
+
+      # Compile the Ruby for this section now that we know what's
+      # inside the section.
+      ev(<<-compiled)
+      if v = #{compile!(name)}
+        if v == true
+          #{code}
+        elsif v.is_a?(Proc)
+          t = Mustache::Template.new(v.call(#{raw.inspect}).to_s)
+          def t.tokens(src=@source)
+            p = Parser.new
+            p.otag, p.ctag = #{delims.inspect}
+            p.compile(src)
+          end
+          t.render(ctx.dup)
+        else
+          # Shortcut when passed non-array
+          v = [v] unless v.is_a?(Array) || defined?(Enumerator) && v.is_a?(Enumerator)
+
+          v.map { |h| ctx.push(h); r = #{code}; ctx.pop; r }.join
+        end
+      end
+      compiled
+    end
+
+    # Fired when we find an inverted section. Just like `on_section`,
+    # we're passed the inverted section name and the array of tokens.
+    def on_inverted_section(name, content, raw, _)
+      # Convert the tokenized content of this section into a Ruby
+      # string we can use.
+      code = compile(content)
+
+      # Compile the Ruby for this inverted section now that we know
+      # what's inside.
+      ev(<<-compiled)
+      v = #{compile!(name)}
+      if v.nil? || v == false || v.respond_to?(:empty?) && v.empty?
+        #{code}
+      end
+      compiled
+    end
+
+    # Fired when the compiler finds a partial. We want to return code
+    # which calls a partial at runtime instead of expanding and
+    # including the partial's body to allow for recursive partials.
+    def on_partial(name, indentation)
+      ev("ctx.partial(#{name.to_sym.inspect}, #{indentation.inspect})")
+    end
+
+    # An unescaped tag.
+    def on_utag(name)
+      ev(<<-compiled)
+        v = #{compile!(name)}
+        if v.is_a?(Proc)
+          v = Mustache::Template.new(v.call.to_s).render(ctx.dup)
+        end
+        v.to_s
+      compiled
+    end
+
+    # An escaped tag.
+    def on_etag(name)
+      ev(<<-compiled)
+        v = #{compile!(name)}
+        if v.is_a?(Proc)
+          v = Mustache::Template.new(v.call.to_s).render(ctx.dup)
+        end
+        ctx.escapeHTML(v.to_s)
+      compiled
+    end
+
+    def on_fetch(names)
+      names = names.map { |n| n.to_sym }
+
+      if names.length == 0
+        "ctx[:to_s]"
+      elsif names.length == 1
+        "ctx[#{names.first.to_sym.inspect}]"
+      else
+        initial, *rest = names
+        <<-compiled
+          #{rest.inspect}.inject(ctx[#{initial.inspect}]) { |value, key|
+            value && ctx.find(value, key)
+          }
+        compiled
+      end
+    end
+
+    # An interpolation-friendly version of a string, for use within a
+    # Ruby string.
+    def ev(s)
+      "#\{#{s}}"
+    end
+
+    def str(s)
+      s.inspect[1..-2]
+    end
+  end
+end

Propchange: incubator/cordova/site/lib/mustache/generator.rb
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/cordova/site/lib/mustache/parser.rb
URL: http://svn.apache.org/viewvc/incubator/cordova/site/lib/mustache/parser.rb?rev=1244800&view=auto
==============================================================================
--- incubator/cordova/site/lib/mustache/parser.rb (added)
+++ incubator/cordova/site/lib/mustache/parser.rb Thu Feb 16 00:12:11 2012
@@ -0,0 +1,263 @@
+require 'strscan'
+
+class Mustache
+  # The Parser is responsible for taking a string template and
+  # converting it into an array of tokens and, really, expressions. It
+  # raises SyntaxError if there is anything it doesn't understand and
+  # knows which sigil corresponds to which tag type.
+  #
+  # For example, given this template:
+  #
+  #   Hi {{thing}}!
+  #
+  # Run through the Parser we'll get these tokens:
+  #
+  #   [:multi,
+  #     [:static, "Hi "],
+  #     [:mustache, :etag, "thing"],
+  #     [:static, "!\n"]]
+  #
+  # You can see the array of tokens for any template with the
+  # mustache(1) command line tool:
+  #
+  #   $ mustache --tokens test.mustache
+  #   [:multi, [:static, "Hi "], [:mustache, :etag, "thing"], [:static, "!\n"]]
+  class Parser
+    # A SyntaxError is raised when the Parser comes across unclosed
+    # tags, sections, illegal content in tags, or anything of that
+    # sort.
+    class SyntaxError < StandardError
+      def initialize(message, position)
+        @message = message
+        @lineno, @column, @line, _ = position
+        @stripped_line = @line.strip
+        @stripped_column = @column - (@line.size - @line.lstrip.size)
+      end
+
+      def to_s
+        <<-EOF
+#{@message}
+  Line #{@lineno}
+    #{@stripped_line}
+    #{' ' * @stripped_column}^
+EOF
+      end
+    end
+
+    # After these types of tags, all whitespace until the end of the line will
+    # be skipped if they are the first (and only) non-whitespace content on
+    # the line.
+    SKIP_WHITESPACE = [ '#', '^', '/', '<', '>', '=', '!' ]
+
+    # The content allowed in a tag name.
+    ALLOWED_CONTENT = /(\w|[?!\/.-])*/
+
+    # These types of tags allow any content,
+    # the rest only allow ALLOWED_CONTENT.
+    ANY_CONTENT = [ '!', '=' ]
+
+    attr_reader :scanner, :result
+    attr_writer :otag, :ctag
+
+    # Accepts an options hash which does nothing but may be used in
+    # the future.
+    def initialize(options = {})
+      @options = {}
+    end
+
+    # The opening tag delimiter. This may be changed at runtime.
+    def otag
+      @otag ||= '{{'
+    end
+
+    # The closing tag delimiter. This too may be changed at runtime.
+    def ctag
+      @ctag ||= '}}'
+    end
+
+    # Given a string template, returns an array of tokens.
+    def compile(template)
+      if template.respond_to?(:encoding)
+        @encoding = template.encoding
+        template = template.dup.force_encoding("BINARY")
+      else
+        @encoding = nil
+      end
+
+      # Keeps information about opened sections.
+      @sections = []
+      @result = [:multi]
+      @scanner = StringScanner.new(template)
+
+      # Scan until the end of the template.
+      until @scanner.eos?
+        scan_tags || scan_text
+      end
+
+      if !@sections.empty?
+        # We have parsed the whole file, but there's still opened sections.
+        type, pos, result = @sections.pop
+        error "Unclosed section #{type.inspect}", pos
+      end
+
+      @result
+    end
+
+    # Find {{mustaches}} and add them to the @result array.
+    def scan_tags
+      # Scan until we hit an opening delimiter.
+      start_of_line = @scanner.beginning_of_line?
+      pre_match_position = @scanner.pos
+      last_index = @result.length
+
+      return unless x = @scanner.scan(/([ \t]*)?#{Regexp.escape(otag)}/)
+      padding = @scanner[1] || ''
+
+      # Don't touch the preceding whitespace unless we're matching the start
+      # of a new line.
+      unless start_of_line
+        @result << [:static, padding] unless padding.empty?
+        pre_match_position += padding.length
+        padding = ''
+      end
+
+      # Since {{= rewrites ctag, we store the ctag which should be used
+      # when parsing this specific tag.
+      current_ctag = self.ctag
+      type = @scanner.scan(/#|\^|\/|=|!|<|>|&|\{/)
+      @scanner.skip(/\s*/)
+
+      # ANY_CONTENT tags allow any character inside of them, while
+      # other tags (such as variables) are more strict.
+      if ANY_CONTENT.include?(type)
+        r = /\s*#{regexp(type)}?#{regexp(current_ctag)}/
+        content = scan_until_exclusive(r)
+      else
+        content = @scanner.scan(ALLOWED_CONTENT)
+      end
+
+      # We found {{ but we can't figure out what's going on inside.
+      error "Illegal content in tag" if content.empty?
+
+      fetch = [:mustache, :fetch, content.split('.')]
+      prev = @result
+
+      # Based on the sigil, do what needs to be done.
+      case type
+      when '#'
+        block = [:multi]
+        @result << [:mustache, :section, fetch, block]
+        @sections << [content, position, @result]
+        @result = block
+      when '^'
+        block = [:multi]
+        @result << [:mustache, :inverted_section, fetch, block]
+        @sections << [content, position, @result]
+        @result = block
+      when '/'
+        section, pos, result = @sections.pop
+        raw = @scanner.pre_match[pos[3]...pre_match_position] + padding
+        (@result = result).last << raw << [self.otag, self.ctag]
+
+        if section.nil?
+          error "Closing unopened #{content.inspect}"
+        elsif section != content
+          error "Unclosed section #{section.inspect}", pos
+        end
+      when '!'
+        # ignore comments
+      when '='
+        self.otag, self.ctag = content.split(' ', 2)
+      when '>', '<'
+        @result << [:mustache, :partial, content, padding]
+      when '{', '&'
+        # The closing } in unescaped tags is just a hack for
+        # aesthetics.
+        type = "}" if type == "{"
+        @result << [:mustache, :utag, fetch]
+      else
+        @result << [:mustache, :etag, fetch]
+      end
+
+      # Skip whitespace and any balancing sigils after the content
+      # inside this tag.
+      @scanner.skip(/\s+/)
+      @scanner.skip(regexp(type)) if type
+
+      # Try to find the closing tag.
+      unless close = @scanner.scan(regexp(current_ctag))
+        error "Unclosed tag"
+      end
+
+      # If this tag was the only non-whitespace content on this line, strip
+      # the remaining whitespace.  If not, but we've been hanging on to padding
+      # from the beginning of the line, re-insert the padding as static text.
+      if start_of_line && !@scanner.eos?
+        if @scanner.peek(2) =~ /\r?\n/ && SKIP_WHITESPACE.include?(type)
+          @scanner.skip(/\r?\n/)
+        else
+          prev.insert(last_index, [:static, padding]) unless padding.empty?
+        end
+      end
+
+      # Store off the current scanner position now that we've closed the tag
+      # and consumed any irrelevant whitespace.
+      @sections.last[1] << @scanner.pos unless @sections.empty?
+
+      return unless @result == [:multi]
+    end
+
+    # Try to find static text, e.g. raw HTML with no {{mustaches}}.
+    def scan_text
+      text = scan_until_exclusive(/(^[ \t]*)?#{Regexp.escape(otag)}/)
+
+      if text.nil?
+        # Couldn't find any otag, which means the rest is just static text.
+        text = @scanner.rest
+        # Mark as done.
+        @scanner.terminate
+      end
+
+      text.force_encoding(@encoding) if @encoding
+
+      @result << [:static, text] unless text.empty?
+    end
+
+    # Scans the string until the pattern is matched. Returns the substring
+    # *excluding* the end of the match, advancing the scan pointer to that
+    # location. If there is no match, nil is returned.
+    def scan_until_exclusive(regexp)
+      pos = @scanner.pos
+      if @scanner.scan_until(regexp)
+        @scanner.pos -= @scanner.matched.size
+        @scanner.pre_match[pos..-1]
+      end
+    end
+
+    # Returns [lineno, column, line]
+    def position
+      # The rest of the current line
+      rest = @scanner.check_until(/\n|\Z/).to_s.chomp
+
+      # What we have parsed so far
+      parsed = @scanner.string[0...@scanner.pos]
+
+      lines = parsed.split("\n")
+
+      [ lines.size, lines.last.size - 1, lines.last + rest ]
+    end
+
+    # Used to quickly convert a string into a regular expression
+    # usable by the string scanner.
+    def regexp(thing)
+      /#{Regexp.escape(thing)}/
+    end
+
+    # Raises a SyntaxError. The message should be the name of the
+    # error - other details such as line number and position are
+    # handled for you.
+    def error(message, pos = position)
+      raise SyntaxError.new(message, pos)
+    end
+  end
+end

Propchange: incubator/cordova/site/lib/mustache/parser.rb
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/cordova/site/lib/mustache/settings.rb
URL: http://svn.apache.org/viewvc/incubator/cordova/site/lib/mustache/settings.rb?rev=1244800&view=auto
==============================================================================
--- incubator/cordova/site/lib/mustache/settings.rb (added)
+++ incubator/cordova/site/lib/mustache/settings.rb Thu Feb 16 00:12:11 2012
@@ -0,0 +1,226 @@
+# Settings which can be configured for all view classes, a single
+# view class, or a single Mustache instance.
+class Mustache
+
+  #
+  # Template Path
+  #
+
+  # The template path informs your Mustache view where to look for its
+  # corresponding template. By default it's the current directory (".")
+  #
+  # A class named Stat with a template_path of "app/templates" will look
+  # for "app/templates/stat.mustache"
+
+  def self.template_path
+    @template_path ||= inheritable_config_for :template_path, '.'
+  end
+
+  def self.template_path=(path)
+    @template_path = File.expand_path(path)
+    @template = nil
+  end
+
+  def template_path
+    @template_path ||= self.class.template_path
+  end
+
+  def template_path=(path)
+    @template_path = File.expand_path(path)
+    @template = nil
+  end
+
+  # Alias for `template_path`
+  def self.path
+    template_path
+  end
+  alias_method :path, :template_path
+
+  # Alias for `template_path`
+  def self.path=(path)
+    self.template_path = path
+  end
+  alias_method :path=, :template_path=
+
+
+  #
+  # Template Extension
+  #
+
+  # A Mustache template's default extension is 'mustache', but this can be changed.
+
+  def self.template_extension
+    @template_extension ||= inheritable_config_for :template_extension, 'mustache'
+  end
+
+  def self.template_extension=(template_extension)
+    @template_extension = template_extension
+    @template = nil
+  end
+
+  def template_extension
+    @template_extension ||= self.class.template_extension
+  end
+
+  def template_extension=(template_extension)
+    @template_extension = template_extension
+    @template = nil
+  end
+
+
+  #
+  # Template Name
+  #
+
+  # The template name is the Mustache template file without any
+  # extension or other information. Defaults to `class_name`.
+  #
+  # You may want to change this if your class is named Stat but you want
+  # to re-use another template.
+  #
+  #   class Stat
+  #     self.template_name = "graphs" # use graphs.mustache
+  #   end
+
+  def self.template_name
+    @template_name || underscore
+  end
+
+  def self.template_name=(template_name)
+    @template_name = template_name
+    @template = nil
+  end
+
+  def template_name
+    @template_name ||= self.class.template_name
+  end
+
+  def template_name=(template_name)
+    @template_name = template_name
+    @template = nil
+  end
+
+
+  #
+  # Template File
+  #
+
+  # The template file is the absolute path of the file Mustache will
+  # use as its template. By default it's ./class_name.mustache
+
+  def self.template_file
+    @template_file || "#{path}/#{template_name}.#{template_extension}"
+  end
+
+  def self.template_file=(template_file)
+    @template_file = template_file
+    @template = nil
+  end
+
+  # The template file is the absolute path of the file Mustache will
+  # use as its template. By default it's ./class_name.mustache
+  def template_file
+    @template_file || "#{path}/#{template_name}.#{template_extension}"
+  end
+
+  def template_file=(template_file)
+    @template_file = template_file
+    @template = nil
+  end
+
+
+  #
+  # Template
+  #
+
+  # The template is the actual string Mustache uses as its template.
+  # There is a bit of magic here: what we get back is actually a
+  # Mustache::Template object, but you can still safely use `template=`
+  #  with a string.
+
+  def self.template
+    @template ||= templateify(File.read(template_file))
+  end
+
+  def self.template=(template)
+    @template = templateify(template)
+  end
+
+  # The template can be set at the instance level.
+  def template
+    return @template if @template
+
+    # If they sent any instance-level options use that instead of the class's.
+    if @template_path || @template_extension || @template_name || @template_file
+      @template = templateify(File.read(template_file))
+    else
+      @template = self.class.template
+    end
+  end
+
+  def template=(template)
+    @template = templateify(template)
+  end
+
+
+  #
+  # Raise on context miss
+  #
+
+  # Should an exception be raised when we cannot find a corresponding method
+  # or key in the current context? By default this is false to emulate ctemplate's
+  # behavior, but it may be useful to enable when debugging or developing.
+  #
+  # If set to true and there is a context miss, `Mustache::ContextMiss` will
+  # be raised.
+
+  def self.raise_on_context_miss?
+    @raise_on_context_miss
+  end
+
+  def self.raise_on_context_miss=(boolean)
+    @raise_on_context_miss = boolean
+  end
+
+  # Instance level version of `Mustache.raise_on_context_miss?`
+  def raise_on_context_miss?
+    self.class.raise_on_context_miss? || @raise_on_context_miss
+  end
+
+  def raise_on_context_miss=(boolean)
+    @raise_on_context_miss = boolean
+  end
+
+
+  #
+  # View Namespace
+  #
+
+  # The constant under which Mustache will look for views when autoloading.
+  # By default the view namespace is `Object`, but it might be nice to set
+  # it to something like `Hurl::Views` if your app's main namespace is `Hurl`.
+
+  def self.view_namespace
+    @view_namespace ||= inheritable_config_for(:view_namespace, Object)
+  end
+
+  def self.view_namespace=(namespace)
+    @view_namespace = namespace
+  end
+
+
+  #
+  # View Path
+  #
+
+  # Mustache searches the view path for .rb files to require when asked to find a
+  # view class. Defaults to "."
+
+  def self.view_path
+    @view_path ||= inheritable_config_for(:view_path, '.')
+  end
+
+  def self.view_path=(path)
+    @view_path = path
+  end
+end

Propchange: incubator/cordova/site/lib/mustache/settings.rb
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/cordova/site/lib/mustache/sinatra.rb
URL: http://svn.apache.org/viewvc/incubator/cordova/site/lib/mustache/sinatra.rb?rev=1244800&view=auto
==============================================================================
--- incubator/cordova/site/lib/mustache/sinatra.rb (added)
+++ incubator/cordova/site/lib/mustache/sinatra.rb Thu Feb 16 00:12:11 2012
@@ -0,0 +1,205 @@
+require 'sinatra/base'
+require 'mustache'
+
+class Mustache
+  # Support for Mustache in your Sinatra app.
+  #
+  #   require 'mustache/sinatra'
+  #
+  #   class Hurl < Sinatra::Base
+  #     register Mustache::Sinatra
+  #
+  #     set :mustache, {
+  #       # Should be the path to your .mustache template files.
+  #       :templates => "path/to/mustache/templates",
+  #
+  #       # Should be the path to your .rb Mustache view files.
+  #       :views => "path/to/mustache/views",
+  #
+  #       # This tells Mustache where to look for the Views module,
+  #       # under which your View classes should live. By default it's
+  #       # the class of your app - in this case `Hurl`. That is, for an :index
+  #       # view Mustache will expect Hurl::Views::Index by default.
+  #       # If our Sinatra::Base subclass was instead Hurl::App,
+  #       # we'd want to do `set :namespace, Hurl::App`
+  #       :namespace => Hurl
+  #     }
+  #
+  #     get '/stats' do
+  #       mustache :stats
+  #     end
+  #   end
+  #
+  # As noted above, Mustache will look for `Hurl::Views::Index` when
+  # `mustache :index` is called.
+  #
+  # If no `Views::Stats` class exists Mustache will render the template
+  # file directly.
+  #
+  # You can indeed use layouts with this library. Where you'd normally
+  # <%= yield %> you instead {{{yield}}} - the body of the subview is
+  # set to the `yield` variable and made available to you.
+  #
+  # If you don't want the Sinatra extension to look up your view class,
+  # maybe because you've already loaded it or you're pulling it in from
+  # a gem, you can hand the `mustache` helper a Mustache subclass directly:
+  #
+  #   # Assuming `class Omnigollum::Login < Mustache`
+  #   get '/login' do
+  #     @title = "Log In"
+  #     require 'lib/omnigollum/views/login'
+  #     mustache Omnigollum::Login
+  #   end
+  #
+  module Sinatra
+    module Helpers
+      # Call this in your Sinatra routes.
+      def mustache(template, options={}, locals={})
+        # Locals can be passed as options under the :locals key.
+        locals.update(options.delete(:locals) || {})
+
+        # Grab any user-defined settings.
+        if settings.respond_to?(:mustache)
+          options = settings.send(:mustache).merge(options)
+        end
+
+        # If they aren't explicitly disabling layouts, try to find
+        # one.
+        if options[:layout] != false
+          # Let the user pass in a layout name.
+          layout_name = options[:layout]
+
+          # If all they said was `true` (or nothing), default to :layout.
+          layout_name = :layout if layout_name == true || !layout_name
+
+          # If they passed a layout name use that.
+          layout = mustache_class(layout_name, options)
+
+          # If it's just an anonymous subclass then don't bother, otherwise
+          # give us a layout instance.
+          if layout.name && layout.name.empty?
+            layout = nil
+          else
+            layout = layout.new
+          end
+        end
+
+        # If instead of a symbol they gave us a Mustache class,
+        # use that for rendering.
+        klass = template if template.is_a?(Class) && template < Mustache
+
+        # Find and cache the view class we want if we don't have
+        # one yet. This ensures the compiled template is cached,
+        # too - no looking up and compiling templates on each page
+        # load.
+        if klass.nil?
+          klass = mustache_class(template, options)
+        end
+
+        # Does the view subclass the layout? If so we'll use the
+        # view to render the layout so you can override layout
+        # methods in your view - tricky.
+        view_subclasses_layout = klass < layout.class if layout
+
+        # Create a new instance for playing with.
+        instance = klass.new
+
+        # Copy instance variables set in Sinatra to the view
+        instance_variables.each do |name|
+          instance.instance_variable_set(name, instance_variable_get(name))
+        end
+
+        # Render with locals.
+        rendered = instance.render(instance.template, locals)
+
+        # Now render the layout with the view we just rendered, if we
+        # need to.
+        if layout && view_subclasses_layout
+          rendered = instance.render(layout.template, :yield => rendered)
+        elsif layout
+          rendered = layout.render(layout.template, :yield => rendered)
+        end
+
+        # That's it.
+        rendered
+      end
+
+      # Returns a View class for a given template name.
+      def mustache_class(template, options = {})
+        @template_cache.fetch(:mustache, template) do
+          compile_mustache(template, options)
+        end
+      end
+
+      # Given a view name and settings, finds and prepares an
+      # appropriate view class for this view.
+      def compile_mustache(view, options = {})
+        options[:templates] ||= settings.views if settings.respond_to?(:views)
+        options[:namespace] ||= self.class
+
+        unless options[:namespace].to_s.include? 'Views'
+          options[:namespace] = options[:namespace].const_get(:Views)
+        end
+
+        factory = Class.new(Mustache) do
+          self.view_namespace = options[:namespace]
+          self.view_path      = options[:views]
+        end
+
+        # If we were handed :"positions.atom" or some such as the
+        # template name, we need to remember the extension.
+        if view.to_s.include?('.')
+          view, ext = view.to_s.split('.')
+        end
+
+        # Try to find the view class for a given view, e.g.
+        # :view => Hurl::Views::Index.
+        klass = factory.view_class(view)
+        klass.view_namespace = options[:namespace]
+        klass.view_path      = options[:views]
+
+        # If there is no view class, issue a warning and use the one
+        # we just generated to cache the compiled template.
+        if klass == Mustache
+          warn "No view class found for #{view} in #{factory.view_path}"
+          klass = factory
+
+          # If this is a generic view class make sure we set the
+          # template name as it was given. That is, an anonymous
+          # subclass of Mustache won't know how to find the
+          # "index.mustache" template unless we tell it to.
+          klass.template_name = view.to_s
+        elsif ext
+          # We got an ext (like "atom"), so look for an "Atom" class
+          # under the current View's namespace.
+          #
+          # So if our template was "positions.atom", try to find
+          # Positions::Atom.
+          if klass.const_defined?(ext_class = ext.capitalize)
+            # Found Positions::Atom - set it
+            klass = klass.const_get(ext_class)
+          else
+            # Didn't find Positions::Atom - create it by creating an
+            # anonymous subclass of Positions and setting that to
+            # Positions::Atom.
+            new_class = Class.new(klass)
+            new_class.template_name = "#{view}.#{ext}"
+            klass.const_set(ext_class, new_class)
+            klass = new_class
+          end
+        end
+
+        # Set the template path and return our class.
+        klass.template_path = options[:templates] if options[:templates]
+        klass
+      end
+    end
+
+    # Called when you `register Mustache::Sinatra` in your Sinatra app.
+    def self.registered(app)
+      app.helpers Mustache::Sinatra::Helpers
+    end
+  end
+end
+
+Sinatra.register Mustache::Sinatra

Propchange: incubator/cordova/site/lib/mustache/sinatra.rb
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/cordova/site/lib/mustache/template.rb
URL: http://svn.apache.org/viewvc/incubator/cordova/site/lib/mustache/template.rb?rev=1244800&view=auto
==============================================================================
--- incubator/cordova/site/lib/mustache/template.rb (added)
+++ incubator/cordova/site/lib/mustache/template.rb Thu Feb 16 00:12:11 2012
@@ -0,0 +1,58 @@
+require 'cgi'
+
+require 'mustache/parser'
+require 'mustache/generator'
+
+class Mustache
+  # A Template represents a Mustache template. It compiles and caches
+  # a raw string template into something usable.
+  #
+  # The idea is this: when handed a Mustache template, convert it into
+  # a Ruby string by transforming Mustache tags into interpolated
+  # Ruby.
+  #
+  # You shouldn't use this class directly, instead:
+  #
+  # >> Mustache.render(template, hash)
+  class Template
+    attr_reader :source
+
+    # Expects a Mustache template as a string along with a template
+    # path, which it uses to find partials.
+    def initialize(source)
+      @source = source
+    end
+
+    # Renders the `@source` Mustache template using the given
+    # `context`, which should be a simple hash keyed with symbols.
+    #
+    # The first time a template is rendered, this method is overriden
+    # and from then on it is "compiled". Subsequent calls will skip
+    # the compilation step and run the Ruby version of the template
+    # directly.
+    def render(context)
+      # Compile our Mustache template into a Ruby string
+      compiled = "def render(ctx) #{compile} end"
+
+      # Here we rewrite ourself with the interpolated Ruby version of
+      # our Mustache template so subsequent calls are very fast and
+      # can skip the compilation stage.
+      instance_eval(compiled, __FILE__, __LINE__ - 1)
+
+      # Call the newly rewritten version of #render
+      render(context)
+    end
+
+    # Does the dirty work of transforming a Mustache template into an
+    # interpolation-friendly Ruby string.
+    def compile(src = @source)
+      Generator.new.compile(tokens(src))
+    end
+    alias_method :to_s, :compile
+
+    # Returns an array of tokens for a given template.
+    def tokens(src = @source)
+      Parser.new.compile(src)
+    end
+  end
+end

Propchange: incubator/cordova/site/lib/mustache/template.rb
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/cordova/site/lib/mustache/version.rb
URL: http://svn.apache.org/viewvc/incubator/cordova/site/lib/mustache/version.rb?rev=1244800&view=auto
==============================================================================
--- incubator/cordova/site/lib/mustache/version.rb (added)
+++ incubator/cordova/site/lib/mustache/version.rb Thu Feb 16 00:12:11 2012
@@ -0,0 +1,3 @@
+class Mustache
+  Version = VERSION = '0.99.4'
+end

Propchange: incubator/cordova/site/lib/mustache/version.rb
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/cordova/site/public/images/cordova_bot.jpg
URL: http://svn.apache.org/viewvc/incubator/cordova/site/public/images/cordova_bot.jpg?rev=1244800&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/cordova/site/public/images/cordova_bot.jpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/cordova/site/public/images/grid.png
URL: http://svn.apache.org/viewvc/incubator/cordova/site/public/images/grid.png?rev=1244800&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/cordova/site/public/images/grid.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/cordova/site/public/images/shadow.png
URL: http://svn.apache.org/viewvc/incubator/cordova/site/public/images/shadow.png?rev=1244800&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/cordova/site/public/images/shadow.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/cordova/site/public/images/sprite.png
URL: http://svn.apache.org/viewvc/incubator/cordova/site/public/images/sprite.png?rev=1244800&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/cordova/site/public/images/sprite.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/cordova/site/public/index.html
URL: http://svn.apache.org/viewvc/incubator/cordova/site/public/index.html?rev=1244800&view=auto
==============================================================================
--- incubator/cordova/site/public/index.html (added)
+++ incubator/cordova/site/public/index.html Thu Feb 16 00:12:11 2012
@@ -0,0 +1,167 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
+<meta name = "format-detection" content = "telephone=no">
+<title>Apache Cordova</title>
+<link rel="stylesheet" type="text/css" href="master.css">
+<script src="js/smooth.pack.js" type="text/javascript"></script>
+</head>
+<body>
+<a class="scroll-point pt-top" name="top"></div>
+<div id="header">
+    <div class="wrap">
+    	<a class="logo" href="#top"></a>
+    	<div class="menu">
+    		<a href="#about">About</a>
+    		<a href="#contribute">Contribute</a>
+    		<a href="#mailing-list">Mailing List</a>
+    		<a href="#download">Download</a>
+            <!-- <a href="#">Docs</a> -->
+    	</div>
+    </div>
+    <div class="shadow"></div>
+</div>
+<div class="header-placeholder"></div>
+
+<div class="grid leadin">
+    <div class="wrap">
+        <img src="images/cordova_bot.jpg" alt=""/>
+        <ul class="text-block">
+            <li><h1><strong>Apache Cordova</strong> is a platform</h1></li>
+            <li><h1>for building native mobile</h1></li>
+            <li><h1>application using <strong>HTML</strong>, <strong>CSS</strong></h1></li>
+            <li><h1>and <strong>JavaScript</strong></h1></li>
+        </ul>
+    </div>
+</div>
+
+<a class="scroll-point pt-about" name="about"></a>
+<div class="wrap">
+    <h2 class="icon icon-about">About Apache Cordova&trade;</h2>
+	<p>Apache Cordova is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Apache Incubator project. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making process have stabilized in a manner consistent with other successful ASF projects. While incubation status is not necessarily a reflection of the completeness or stability of the code, it does indicate that the project has yet to be fully endorsed by the ASF.</p>
+</div>
+<a class="scroll-point" name="contribute"></a>
+<hr/>
+
+<div class="wrap">
+    <h2 class="icon icon-contribute">Want to Contribute?</h2>
+	<p>First, make sure you have signed the <a href="http://www.apache.org/licenses/#clas">Apache CLA</a>.</p>
+	<p>The <a href="https://issues.apache.org/jira/browse/">JIRA issue tracker</a> and the <a href="#mailing-list">dev mailing list</a> are good places to identify areas to help out in.</p>
+	<p>Next, clone the git repository for the project you are wishing to contribute to (see below). We recommend employing a certain type of git workflow, please see our <a href="http://wiki.apache.org/cordova/ContributerWorkflow">wiki article</a> for more information.</p>
+	<p>Finally, to share your changes with the community, you can send a pull request on GitHub to the Apache git mirrors. You can also advocate for your changes directly on our <a href="#mailing-list">mailing list</a>.</p>
+	<p>For detailed instruction on how to contribute for a specific platform / topic, choose from below:</p>
+</div>
+
+<div class="grid">
+    <div class="wrap">
+        <div class="corner"></div>
+        <ul class="list platforms-list">
+			<li class="first">Android<a class="link-apache" href="https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-android.git;a=summary"></a><a class="link-github" href="https://github.com/apache/incubator-cordova-android"></a></li><li >Bada<a class="link-apache" href="https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-bada.git;a=summary"></a><a class="link-github" href="https://github.com/apache/incubator-cordova-bada"></a></li><li >Blackberry<a class="link-apache" href="https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-blackberry-webworks.git;a=summary"></a><a class="link-github" href="https://github.com/apache/incubator-cordova-blackberry-webworks"></a></li><li >iOS<a class="link-apache" href="https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-ios.git;a=summary"></a><a class="link-github" href="https://github.com/apache/incubator-cordova-ios"></a></li><li >Mac OS X<a class="link-apache" href="https://git-wip-us.apache.org/repos/asf?p=incubat
 or-cordova-mac.git;a=summary"></a><a class="link-github" href="https://github.com/apache/incubator-cordova-mac"></a></li><li >WebOS<a class="link-apache" href="https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-webos.git;a=summary"></a><a class="link-github" href="https://github.com/apache/incubator-cordova-webos"></a></li><li >Windows Phone<a class="link-apache" href="https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-wp7.git;a=summary"></a><a class="link-github" href="https://github.com/apache/incubator-cordova-wp7"></a></li>
+		</ul>		
+		<ul class="list platforms-list second">
+			<li class="first">Docs<a class="link-apache" href="https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-docs.git;a=summary"></a><a class="link-github" href="https://github.com/apache/incubator-cordova-docs"></a></li><li >Mobile Spec<a class="link-apache" href="https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-mobile-spec.git;a=summary"></a><a class="link-github" href="https://github.com/apache/incubator-cordova-mobile-spec"></a></li><li >Weinre<a class="link-apache" href="https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-weinre.git;a=summary"></a><a class="link-github" href="https://github.com/apache/incubator-cordova-weinre"></a></li>
+		</ul>
+    </div>
+</div>
+
+<a class="scroll-point" name="mailing-list"></a>
+<hr/>
+
+<div class="wrap">
+    <h2 class="icon icon-mailing-list">Mailing List</h2>
+</div>
+
+<div class="grid">
+    <div class="wrap">	
+        <div class="corner"></div>
+        <br/>
+	    <div class="list-header">
+			<strong>Dev Mailing List</strong>
+			<p>Dev mailing list is a place for discussion about Apache Cordova projects.</p>
+		</div>
+		<ul class="list mailing-list">
+			<li>Writing to the list<a href="mailto:callback-dev@incubator.apache.org">callback-dev@incubator.apache.org<span></span></a></li>
+			<li>Subscription address<a href="mailto:callback-dev-subscribe@incubator.apache.org">callback-dev-subscribe@incubator.apache.org<span></span></a></li>
+			<li>Digest subscription address<a href="mailto:callback-dev-digest-subscribe@incubator.apache.org">callback-dev-digest-subscribe@incubator.apache.org<span></span></a></li>
+			<li>Unsubscription addresses<a href="mailto:callback-dev-unsubscribe@incubator.apache.org">callback-dev-unsubscribe@incubator.apache.org<span></span></a></li>
+			<li>Getting help with the list<a href="mailto:callback-dev-help@incubator.apache.org">callback-dev-help@incubator.apache.org<span></span></a></li> 
+		</ul>
+		<br/>
+		<div class="list-header">
+			<strong>Commits Mailing List</strong>
+			<p>Commits mailing list tracks commit logs for Apache Cordova repos.</p>
+		</div>
+		<ul class="list mailing-list">
+			<li>Writing to the list<a href="mailto:callback-commits@incubator.apache.org">callback-commits@incubator.apache.org<span></span></a></li>
+			<li>Subscription address<a href="mailto:callback-commits-subscribe@incubator.apache.org">callback-commits-subscribe@incubator.apache.org<span></span></a></li>
+			<li>Digest subscription address<a href="mailto:callback-commits-digest-subscribe@incubator.apache.org">callback-commits-digest-subscribe@incubator.apache.org<span></span></a></li>
+			<li>Unsubscription addresses<a href="mailto:callback-commits-unsubscribe@incubator.apache.org">callback-commits-unsubscribe@incubator.apache.org<span></span></a></li>
+			<li>Getting help with the list<a href="mailto:callback-commits-help@incubator.apache.org">callback-commits-help@incubator.apache.org<span></span></a></li>
+		</ul>
+	</div>
+</div>
+
+<a class="scroll-point" name="download"></a>
+<hr/>
+
+<div class="wrap download-pane">
+    <h2 class="icon icon-download">Download &amp; Archives</h2>
+	<p>By downloading, you agree to the <a href="#">terms of service</a>.</p>
+	<div class="button-container">
+    	<div class="button">Coming Soon<label></label></div>
+	</div>
+</div>
+
+<div class="grid">
+    <div class="wrap">
+        <div class="corner"></div>
+		<br/>
+		<br/>
+    </div>
+</div>
+
+<hr/>
+
+<div class="wrap quick-links-pane">
+    <h2 class="icon icon-quick-links">Quick Links</h2>
+	<br/>
+	<ul class="quick-links-header">
+		<li>General</li>
+		<li>Development</li>
+		<li class="last">Apache Software Foundation</li>
+	</ul>
+	<div class="clear"></div>
+</div>
+
+<div class="grid">
+    <div class="wrap">
+		<div class="list-container">
+			<div class="list quick-links">
+                <li class="corner"></li>
+				<li><a href="#about">About Cordova<span></span></a></li><li><a href="http://incubator.apache.org/projects/callback.html">Incubator Page<span></span></a></li><li><a href="http://www.apache.org/licenses/LICENSE-2.0">License<span></span></a></li>
+			</div>
+
+			<ul class="list quick-links">
+                <li class="corner"></li>
+				<li><a href="#download">Download<span></span></a></li><li><a href="https://git-wip-us.apache.org/repos/asf">Source Code<span></span></a></li><li><a href="http://www.apache.org/licenses/LICENSE-2.0">License<span></span></a></li><li><a href="#mailing-list">Mailing List<span></span></a></li><li><a href="https://issues.apache.org/jira/browse/CB">Issue Tracker<span></span></a></li><li><a href="http://wiki.apache.org/cordova/">Wiki<span></span></a></li>
+			</ul>
+
+			<ul class="list quick-links last">
+                <li class="corner"></li>
+				<li><a href="http://www.apache.org/">About ASF<span></span></a></li><li><a href="http://www.apache.org/foundation/thanks.html">Thanks<span></span></a></li><li><a href="http://www.apache.org/foundation/sponsorship.html">Become a Sponsor<span></span></a></li><li><a href="http://www.apache.org/security/">Security<span></span></a></li>
+			</ul>
+			
+			<div class="clear"></div>
+		</div>
+    </div>
+</div>
+
+<div id="footer">
+	<p>Copyright © 2012 The Apache Software Foundation, Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.<br/>
+	Apache and the Apache feather logos are trademarks of The Apache Software Foundation.</p>
+	<a class="closing" href="#top"></a>
+</div>
+
+</body>
+</html>

Added: incubator/cordova/site/public/js/smooth.pack.js
URL: http://svn.apache.org/viewvc/incubator/cordova/site/public/js/smooth.pack.js?rev=1244800&view=auto
==============================================================================
--- incubator/cordova/site/public/js/smooth.pack.js (added)
+++ incubator/cordova/site/public/js/smooth.pack.js Thu Feb 16 00:12:11 2012
@@ -0,0 +1,2 @@
+//dezinerfolio
+eval((function(){a="Scroller={speed:10,8dC.;d.while(dC.+C.}} J8N;d=5;&&M4M}d&&dM4dM}%4%} 0J8a,F4(F,fa@7a.4a.LP+F7Jend8e66.cancelBubble=true;6.Value=fa@;}&&(E(7J8di=Hner3||5.G3;hN.3;a=(Ed>ah-d>i7e@{-(h-d)7}e@{a=a+(d-a}To(0,aEa==a}=aJHit8KwHdow,A,A7,A82P;l=9;d=locatiP;D&&D.HdexOfL#)!=-1&&(l/+l=C)Kl,Gck,endEl.PGck=2l=this.hash.substr(1E9.name==l;i=setILL+(9)+),107}}}}}};Hit()",b=48;while(b>=0)a=a.replace(new RegExp("%23456789@ACDEFGHJKLMNP".charAt(b),"g"),("\042Scroller.entfunction(offsetParscrollwindow.returndocumattachEvntervala=.getElemsByTagName(a);if(offsetTop){for(i=0;i<a.length;i++.pathnamea+=Math.ceil((d-ae.stopPropagationTopa.addEvListenerbody)/speede.prevDefaultclearI(i)pageYOffsetend(this);Height .Elemev)}:a[i]lseload=dl.href);b,dcliin},((.=.=C||on".split(""))
 [b--]);return a})())
\ No newline at end of file

Propchange: incubator/cordova/site/public/js/smooth.pack.js
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/cordova/site/public/master.css
URL: http://svn.apache.org/viewvc/incubator/cordova/site/public/master.css?rev=1244800&view=auto
==============================================================================
--- incubator/cordova/site/public/master.css (added)
+++ incubator/cordova/site/public/master.css Thu Feb 16 00:12:11 2012
@@ -0,0 +1,92 @@
+*{margin:0;padding:0;}
+body,a{color:#3b4854;}
+.animate-background{-webkit-transition:background 0.25s linear;-moz-transition:background 0.25s linear;transition:background 0.25s linear;}
+.animate{-webkit-transition:all 0.25s linear;-moz-transition:all 0.25s linear;transition:all 0.25s linear;}
+.secondary-bg{background:url(images/grid.png) #eeeeee 50% 0%;}
+.sprite{background:url(images/sprite.png) no-repeat;}
+body,h1,h2,h3,h4{font-size:16px;font-family:'HelveticaNeue-Light',Helvetica,Arial,sans-serif;font-weight:300;}
+h1,h2,h3,h4{letter-spacing:0.05em;}
+h1{font-size:34px;}
+h2{font-size:34px;padding:48px 0;}
+b,strong{font-family:'HelveticaNeue-Bold',Helvetica,Arial,sans-serif;font-weight:900;}
+label{font-family:'HelveticaNeue',Helvetica,Arial,sans-serif;font-weight:400;font-size:12px;}
+.platforms-list li,.list-header.mini,.quick-links-header li{font-family:'HelveticaNeue-Medium','HelveticaNeue',Helvetica,Arial,sans-serif;font-weight:500;}
+a:hover{color:#4cc2e4;}
+p{line-height:2em;margin-bottom:2em;}
+p+p{margin-top:2em;}
+.button-container{position:absolute;right:-5px;background:url(images/shadow.png);}
+.button{display:block;background:url(images/sprite.png) no-repeat;background-color:#4cc2e4;background-position:100% -171px;width:288px;padding:16px;color:#fff;font-size:24px;text-decoration:none;position:relative;top:-5px;left:-5px;-webkit-transition:background 0.25s linear;-moz-transition:background 0.25s linear;transition:background 0.25s linear;}
+.button:hover{background-color:#4cd6fc;color:#fff;}
+div.button,div.button:hover{background-color:#abafb0;}
+.button label{display:block;font-size:0.5em;height:16px;}
+.clear{clear:both;}
+#wrap,.wrap,#footer,hr{width:1008px;margin:0 auto;position:relative;}
+.grid{background:url(images/grid.png) #eeeeee 50% 0%;padding:32px 0;}
+hr{border:none;border-top:1px solid #ddd;margin-top:64px;margin-bottom:32px;}
+.header-placeholder{height:90px;}
+#header{height:90px;position:fixed;z-index:10;left:0;right:0;background:#fff;border-bottom:1px solid #ddd;}
+#header .shadow{position:absolute;left:0;right:0;bottom:-3px;height:3px;background:url(images/shadow.png);}
+.logo,.closing{background:url(images/sprite.png) no-repeat;-webkit-transition:background 0.25s linear;-moz-transition:background 0.25s linear;transition:background 0.25s linear;background-color:#3b4854;background-position:0 0px;position:absolute;left:0;top:5px;width:220px;height:75px;}
+.logo:hover{background-color:#4cc2e4;}
+.menu{padding:16px 0;float:right;}
+.menu a{text-decoration:none;-webkit-transition:all 0.25s linear;-moz-transition:all 0.25s linear;transition:all 0.25s linear;padding:16px;margin:0 8px;line-height:55px;}
+.menu a:hover{color:#4cc2e4;}
+.leadin{margin-bottom:32px;}
+.leadin .wrap{height:368px;}
+.leadin .text-block{position:absolute;left:384px;top:64px;}
+.leadin img{position:absolute;top:32px;left:24px;}
+.leadin li{list-style:none;margin:9px 8px;}
+.leadin h1{background:#fff;display:inline;padding:4px 8px;}
+.leadin .button-container{bottom:0;}
+.container-box{background:#fff;padding:8px;position:relative;}
+.list-link{position:absolute;top:0;bottom:0;right:0;}
+.list{padding-top:16px;}
+.list li{background:#fff;padding:8px;position:relative;list-style:none;margin-bottom:16px;}
+.list-header{background:#fff;padding:8px;position:relative;margin-top:16px;}
+.list-header p{margin-bottom:0;}
+.list-container{position:relative;}
+.platforms-list{padding-top:32px;width:456px;}
+.platforms-list.second{position:absolute;right:0;top:0;}
+.platforms-list li a{position:absolute;top:0;bottom:0;right:0;-webkit-transition:background 0.25s linear;-moz-transition:background 0.25s linear;transition:background 0.25s linear;width:36px;background:url(images/sprite.png) no-repeat;background-position:3px -127px;background-color:#4cc2e4;}
+.platforms-list li a:hover{background-color:#4cd6fc;}
+.platforms-list li.first a{width:108px;}
+.platforms-list li a.link-apache{right:39px;background-position:2px -94px;}
+.platforms-list li.first a.link-apache{width:144px;right:111px;}
+.mailing-list{width:752px;margin-bottom:24px;}
+.mailing-list a{position:absolute;top:0;bottom:0;right:0;-webkit-transition:all 0.25s linear;-moz-transition:all 0.25s linear;transition:all 0.25s linear;backround:#fff;padding:8px;width:408px;font-size:14px;}
+.mailing-list a:hover{color:#fff;background:#4cc2e4;}
+.mailing-list a span{position:absolute;top:0;bottom:0;right:0;width:36px;background:url(images/sprite.png) no-repeat;background-position:-156px -95px;background-color:#4cc2e4;}
+.mailing-list li{margin-bottom:3px;}
+.download-pane .button-container{bottom:-70px;}
+.list-header.mini{display:inline;}
+.download-list-container{position:relative;}
+.download-list{width:320px;margin-bottom:24px;}
+.download-list.second,.download-list.third{position:absolute;top:0;}
+.download-list.second{left:344px;}
+.download-list.third{left:688px;}
+.download-list li{height:18px;}
+.download-list .version{position:absolute;top:0;bottom:0;right:0;-webkit-transition:background 0.25s linear;-moz-transition:background 0.25s linear;transition:background 0.25s linear;background:url(images/sprite.png) no-repeat;background-position:-160px -127px;background-color:#4cc2e4;color:#fff;text-decoration:none;right:auto;left:0;padding:8px;padding-left:32px;width:40%;}
+.download-list .version:hover{background-color:#4cd6fc;}
+.download-list .release{float:right;font-size:12px;margin-top:2px;}
+.list-header.mini{display:inline;}
+.quick-links,.quick-links-header li{float:left;width:320px;margin-right:24px;list-style:none;position:relative;}
+.quick-links-header li{margin-bottom:24px;}
+.quick-links.last,.quick-links-header li.last{margin-right:0;}
+.quick-links li{padding:0;}
+.quick-links a{-webkit-transition:all 0.25s linear;-moz-transition:all 0.25s linear;transition:all 0.25s linear;display:block;text-decoration:none;padding:8px;}
+.quick-links a:hover{color:#fff;background:#4cc2e4;}
+.quick-links a span{position:absolute;top:0;bottom:0;right:0;width:36px;background:url(images/sprite.png) no-repeat;background-position:-156px -95px;background-color:#4cc2e4;}
+#footer{padding:32px 0 64px;}
+#footer p{font-size:12px;line-height:1.5em;}
+.closing{background-position:0 -725px;left:auto;right:0;top:20px;width:60px;height:65px;}
+.closing:hover{background-color:#4cc2e4;}
+.icon{background:url(images/sprite.png) no-repeat;background-position:0 -220px;padding-left:78px;}
+.icon-about{background-position:0 -220px;}
+.icon-contribute{background-position:0 -316px;}
+.icon-mailing-list{background-position:0 -412px;}
+.icon-download{background-position:0 -508px;}
+.icon-quick-links{background-position:0 -604px;}
+a.scroll-point{display:block;border-bottom:transparent 1px solid;}
+a.pt-top{border:none;}
+a.pt-about{margin:-100px 0 130px;border:none;}
+.corner,.quick-links .corner{background:url(images/sprite.png) no-repeat;background-position:0 -808px;position:absolute;left:0;top:-32px;width:40px;height:40px;}

Added: incubator/cordova/site/www/images/cordova_bot.jpg
URL: http://svn.apache.org/viewvc/incubator/cordova/site/www/images/cordova_bot.jpg?rev=1244800&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/cordova/site/www/images/cordova_bot.jpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/cordova/site/www/images/grid.png
URL: http://svn.apache.org/viewvc/incubator/cordova/site/www/images/grid.png?rev=1244800&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/cordova/site/www/images/grid.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/cordova/site/www/images/shadow.png
URL: http://svn.apache.org/viewvc/incubator/cordova/site/www/images/shadow.png?rev=1244800&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/cordova/site/www/images/shadow.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/cordova/site/www/images/sprite.png
URL: http://svn.apache.org/viewvc/incubator/cordova/site/www/images/sprite.png?rev=1244800&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/cordova/site/www/images/sprite.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream