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™</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 & 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