Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit 646513a3023811c0b28db2f09f0446f3a1718261 @wycats committed Aug 26, 2010
@@ -0,0 +1,2 @@
+pkg/*
+*.gem
@@ -0,0 +1,4 @@
+source :gemcutter
+
+# Specify your gem's dependencies in abbot-ng.gemspec
+gemspec
@@ -0,0 +1,2 @@
+require 'bundler'
+Bundler::GemHelper.install_tasks
@@ -0,0 +1,4 @@
+#!/usr/bin/env ruby
+
+require "sproutcore"
+SproutCore::Server.new.start
@@ -0,0 +1,5 @@
+require "sproutcore/entries"
+require "sproutcore/manifest"
+require "sproutcore/html"
+require "sproutcore/server"
+require "sproutcore/version"
@@ -0,0 +1,211 @@
+require "tsort"
+
+Entry = Struct.new(:name, :requires, :source) do
+
+end
+
+# Construct a special Array that uses the Ruby TSort
+# module to sort files by their dependencies
+module SproutCore
+ class Entries < Array
+ include TSort
+
+ # TSort requires that tsort_each_node iterates through
+ # all nodes. Since this is an Array, alias to each
+ alias tsort_each_node each
+
+ class << self
+ attr_accessor :ext
+ attr_accessor :locale
+ attr_accessor :theme
+ end
+
+ LOCALE_MAP = {"en" => "english", "english" => "en"}
+
+ # Create a new Entries list through Entries.from_directory
+ def self.from_directory(dir, target, target_type = :frameworks)
+ list = new(dir, target, target_type)
+ list.sort!
+ end
+
+ def initialize(dir, target, target_type)
+ @directory = File.expand_path(dir)
+ @target_dir = "#{@directory}/#{target_type}/#{target}"
+ @entry_lookup = {}
+
+ Dir["#{@target_dir}/**/*.#{self.class.ext}"].each do |file|
+ source = File.read(file)
+ requires = source.scan(%r{sc_require\(\s*['"](.*)['"]\)}).flatten
+
+ add Entry.new(file[%r{#{@target_dir}/(.*)\.#{self.class.ext}}, 1], requires, source)
+ end
+
+ # make it faster to look up an entry by name, since
+ # dependencies are Strings
+ @target = target
+ @target_type = target_type
+ @package = File.basename(@directory)
+ end
+
+ def inspect
+ "#<Entries: #{map(&:name).join(", ")}>"
+ end
+
+ def manifest(root_manifest)
+ @manifest = root_manifest
+ self
+ end
+
+ def add(entry)
+ self << entry
+ @entry_lookup[entry.name] = entry
+ end
+
+ def compile
+ output = inject("") do |output, file|
+ output << "/* >>>>>>>>>> BEGIN #{file.name}.#{self.class.ext} */\n"
+ output << "#{file.source}\n"
+ end
+ end
+
+ # sort first by the naming heuristics, then by dependencies
+ def sort!
+ # define sorting heuristics in a subclass
+ end
+
+ private
+ def destination_root
+ "/static/#{LOCALE_MAP[self.class.locale]}/#{@target}"
+ end
+
+ # TSort requires that tsort_each_child take in a node
+ # and then yield back once for each dependency.
+ def tsort_each_child(node)
+ node.requires.each do |name|
+ if entry = @entry_lookup[name]
+ yield entry
+ else
+ puts "WARN: #{node.name} required #{name}, but it could not be found"
+ end
+ end
+ end
+ end
+
+ class JavaScriptEntries < Entries
+ self.ext = "js"
+
+ def compile
+ super << %[\nSC.bundleDidLoad("#{@package}/#{@target}");\n]
+ end
+
+ def sort!
+ step1 = sort_by! do |entry|
+ sort_by = case entry.name
+ # TODO: Allow preferred filename customization
+ when %r{^(\w+\.)lproj/strings$} then -3
+ when "core" then -2
+ when "utils" then -1
+ when %r{^(lproj|resources)/.*_page$} then 1
+ when "main" then 2
+ else 0
+ end
+
+ [sort_by, entry.name]
+ end
+ replace(tsort)
+ end
+
+ def destination(default = "javascript.js")
+ super
+ end
+ end
+
+ class CssEntries < Entries
+ StaticEntry = Struct.new(:source, :destination)
+
+ self.ext = "css"
+
+ self.locale = "english" # hardcode for now
+ self.theme = "standard_theme" # hardcode for now
+
+ attr_accessor :statics
+
+ def initialize(*)
+ super
+
+ @statics = {}
+
+ Dir["#{@target_dir}/**/*.{gif,jpg,png}"].each do |file|
+ file =~ %r{^#{@directory}/#{@target_type}/#{@target}/(?:#{self.class.locale}\.lproj\/)?(.*)$}
+ add_static(file, $1)
+ end
+ end
+
+ def add_static(source, relative)
+ # TODO: Deal with non-English locale getting overridden, probably by sorting the statics
+ # before passing them in for processing
+ relative =~ %r{^((?:#{self.class.locale}\.lproj|english\.lproj|resources)/)?(images/)?(.*)(\.(gif|jpg|png))$}
+
+ destination = "#{destination_root}/#{$3}#{$4}"
+ entry = StaticEntry.new(source, destination)
+
+ @statics["#{$2}#{$3}#{$4}"] = entry
+ @statics["#{$3}#{$4}"] = entry
+ @statics["#{$2}#{$3}"] = entry
+ @statics[$3] = entry
+ end
+
+ def static_or_fallback(static)
+ @statics[static] || @manifest.find_static(static)
+ end
+
+ def sort!
+ sort_by!(&:name)
+ end
+
+ def compile
+ each do |entry|
+ entry.source.gsub!(/(sc_static|static_url|sc_target)\(\s*['"](.+)['"]\s*\)/) do |resource|
+ url = static_or_fallback($2)
+
+ if url && url.destination
+ "url('#{url.destination}')"
+ else
+ puts "WARN: static not found: #{$2} (from #{entry.name}"
+ end
+ end
+ end
+
+ super
+ end
+
+ def destination(default = "stylesheet.js")
+ super
+ end
+ end
+end
+
+__END__
+
+puts Benchmark.measure {
+Dir[File.expand_path("~/Code/sprout/sproutcore/frameworks/*")].each do |file|
+ begin
+ puts File.basename(file)
+ puts Benchmark.measure { SproutCore::CssEntries.from_directory("~/Code/sprout/sproutcore", File.basename(file)).compile }
+ rescue TSort::Cyclic => e
+ puts "Could not sort #{File.basename(file)}: #{e.message}"
+ end
+end
+}
+
+__END__
+puts Benchmark.measure {
+Dir[File.expand_path("~/Code/sprout/sproutcore/frameworks/*")].each do |file|
+ begin
+ puts File.basename(file)
+ puts Benchmark.measure { SproutCore::JavaScriptEntries.from_directory("~/Code/sprout/sproutcore", File.basename(file)).compile }
+ rescue TSort::Cyclic => e
+ puts "Could not sort #{File.basename(file)}: #{e.message}"
+ end
+end
+}
@@ -0,0 +1,42 @@
+module SproutCore
+ class HtmlContext
+ def initialize(config, manifest)
+ @config, @manifest = config, manifest
+
+ @bootstrap = bootstrap
+ @content_for_body = content_for_body
+ end
+
+ def sc_static(static)
+ if static = manifest.find_static(static)
+ static.destination
+ else
+ raise "#{static} could not be found in any of the loaded frameworks, themes, or your app"
+ end
+ end
+
+ def bootstrap
+ location = @manifest.find_js("bootstrap").destination
+ %{<script type='text/javascript' src="#{location}"></script>}
+ end
+
+ def stylesheets
+ sheets = []
+ @manifest.stylesheets.each do |name, list|
+ location = list.destination
+ sheets = %{<link href="#{location} rel="stylesheet" type="text/css" />}
+ end
+ sheets.join("\n")
+ end
+
+ def javascripts
+ scripts = []
+ @manifest.javascripts.each do |name, list|
+ location = list.destination
+ scripts << %{<script type="text/javascript" src="#{location}"></script>}
+ end
+ scripts << %{<script type="text/javascript>String.preferredLanguage = "en";</script>}
+ end
+ scripts.join("\n")
+ end
+end
@@ -0,0 +1,78 @@
+module SproutCore
+ class Manifest
+ def initialize
+ @javascripts = {}
+ @stylesheets = {}
+ end
+
+ def add_target(root, target, target_type)
+ @javascripts[target] = JavaScriptEntries.from_directory(root, target, target_type).manifest(self)
+ @stylesheets[target] = CssEntries.from_directory(root, target, target_type).manifest(self)
+ end
+
+ def puts(*)
+ end
+
+ def find_static(static)
+ @stylesheets.each do |target, list|
+ if found_static = list.statics[static]
+ return found_static
+ end
+ end
+ nil
+ end
+
+ def javascripts
+ @javascripts.each do |k,v|
+ puts
+ puts k
+ puts "<<<<========================>>>>"
+ puts v.compile
+ puts
+ end
+ end
+
+ def stylesheets
+ @stylesheets.each do |k,v|
+ puts
+ puts k
+ puts "<<<<========================>>>>"
+ puts v.compile
+ puts
+ end
+ end
+ end
+end
+
+__END__
+
+manifest = SproutCore::Manifest.new
+
+require "benchmark"
+
+puts Benchmark.measure {
+ %w(bootstrap runtime foundation datastore statechart desktop media).each do |target|
+ manifest.add_target("~/Code/sprout/sproutcore", target, :frameworks)
+ end
+
+ manifest.add_target("~/Code/sprout/sproutcore", "standard_theme", :themes)
+}
+
+puts Benchmark.measure {
+ manifest.javascripts.each do |name, js|
+ puts "Compiling JS: #{name}"
+ js.compile
+ end
+
+ manifest.stylesheets.each do |name, css|
+ puts "Compiling CSS: #{name}"
+ css.compile
+ end
+}
+
+
+# p manifest.find_static("sproutcore-logo.png")
+
+#manifest.add_target("~/Code/sprout/sproutcore", "standard_theme", :themes)
+
+#manifest.stylesheets
@@ -0,0 +1,23 @@
+module SproutCore
+ class Server < ::Rack::Server
+ def initialize
+ @sproutcore = File.expand_path("~/Code/sprout/sproutcore")
+ @manifest = SproutCore::Manifest.new
+
+ %w(bootstrap runtime foundation datastore statechart desktop media).each do |target|
+ manifest.add_target(@sproutcore, target, :frameworks)
+ end
+
+ manifest.add_target(@sproutcore, "standard_theme", :themes)
+
+ @template = Erubis::Eruby.new(File.read(File.expand_path("../templates/index.erb", __FILE__)))
+ end
+
+ def app
+ path = ENV["PATH_INFO"]
+
+ end
+ end
+end
+
+
Oops, something went wrong.

0 comments on commit 646513a

Please sign in to comment.