ymdp 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/lib/application_view/application_view.rb +210 -0
- data/lib/application_view/asset_tag_helper.rb +106 -0
- data/lib/application_view/commands/generate.rb +3 -0
- data/lib/application_view/compiler/template_compiler.rb +417 -0
- data/lib/application_view/config.rb +39 -0
- data/lib/application_view/environment.rb +29 -0
- data/lib/application_view/generator/base.rb +15 -0
- data/lib/application_view/generator/templates/javascript.js +51 -0
- data/lib/application_view/generator/templates/stylesheet.css +5 -0
- data/lib/application_view/generator/templates/translation.pres +8 -0
- data/lib/application_view/generator/templates/view.html.haml +8 -0
- data/lib/application_view/generator/view.rb +170 -0
- data/lib/application_view/helpers.rb +4 -0
- data/lib/application_view/processor/compressor.rb +81 -0
- data/lib/application_view/processor/processor.rb +132 -0
- data/lib/application_view/processor/validator.rb +125 -0
- data/lib/application_view/support/file.rb +54 -0
- data/lib/application_view/support/form_post.rb +58 -0
- data/lib/application_view/support/g.rb +11 -0
- data/lib/application_view/support/growl.rb +36 -0
- data/lib/application_view/support/timer.rb +40 -0
- data/lib/application_view/support/w3c.rb +22 -0
- data/lib/application_view/tag_helper.rb +147 -0
- data/lib/application_view/translator/base.rb +387 -0
- data/lib/application_view/translator/blank.rb +58 -0
- data/lib/application_view/translator/ymdp_translate.rb +92 -0
- data/lib/ymdp.rb +1 -0
- data/test/helper.rb +10 -0
- data/test/test_ymdp.rb +4 -0
- data/ymdp.gemspec +77 -0
- metadata +92 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Jeff Coleman
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
= ymdp
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Note on Patches/Pull Requests
|
6
|
+
|
7
|
+
* Fork the project.
|
8
|
+
* Make your feature addition or bug fix.
|
9
|
+
* Add tests for it. This is important so I don't break it in a
|
10
|
+
future version unintentionally.
|
11
|
+
* Commit, do not mess with rakefile, version, or history.
|
12
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
13
|
+
* Send me a pull request. Bonus points for topic branches.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2010 Jeff Coleman. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "ymdp"
|
8
|
+
gem.summary = "Framework for developing applications in the Yahoo! Mail Development Platform"
|
9
|
+
gem.description = "Framework for developing applications in the Yahoo! Mail Development Platform."
|
10
|
+
gem.email = "progressions@gmail.com"
|
11
|
+
gem.homepage = "http://github.com/progressions/ymdp"
|
12
|
+
gem.authors = ["Jeff Coleman"]
|
13
|
+
# gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rake/testtask'
|
22
|
+
Rake::TestTask.new(:test) do |test|
|
23
|
+
test.libs << 'lib' << 'test'
|
24
|
+
test.pattern = 'test/**/test_*.rb'
|
25
|
+
test.verbose = true
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
require 'rcov/rcovtask'
|
30
|
+
Rcov::RcovTask.new do |test|
|
31
|
+
test.libs << 'test'
|
32
|
+
test.pattern = 'test/**/test_*.rb'
|
33
|
+
test.verbose = true
|
34
|
+
end
|
35
|
+
rescue LoadError
|
36
|
+
task :rcov do
|
37
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
task :test => :check_dependencies
|
42
|
+
|
43
|
+
task :default => :test
|
44
|
+
|
45
|
+
require 'rake/rdoctask'
|
46
|
+
Rake::RDocTask.new do |rdoc|
|
47
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
48
|
+
|
49
|
+
rdoc.rdoc_dir = 'rdoc'
|
50
|
+
rdoc.title = "ymdp #{version}"
|
51
|
+
rdoc.rdoc_files.include('README*')
|
52
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.3
|
@@ -0,0 +1,210 @@
|
|
1
|
+
require 'config'
|
2
|
+
require 'processor/compressor'
|
3
|
+
require 'processor/validator'
|
4
|
+
require 'support/file'
|
5
|
+
|
6
|
+
class Application
|
7
|
+
def self.current_view?(view)
|
8
|
+
current_view.downcase == view.downcase
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.current_view
|
12
|
+
@@current_view
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.current_view= view
|
16
|
+
@@current_view = view
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module ApplicationView
|
21
|
+
module Base
|
22
|
+
include ApplicationView::Config
|
23
|
+
include ApplicationView::FileSupport
|
24
|
+
include ApplicationView::Compressor
|
25
|
+
|
26
|
+
extend self
|
27
|
+
|
28
|
+
def supported_languages
|
29
|
+
dirs = Dir["#{BASE_PATH}/app/assets/yrb/*"].map do |path|
|
30
|
+
filename = path.split("/").last
|
31
|
+
|
32
|
+
filename
|
33
|
+
end
|
34
|
+
|
35
|
+
dirs.unshift(dirs.delete("en-US"))
|
36
|
+
|
37
|
+
raise "Default YRB key en-US not found" unless dirs.include?("en-US")
|
38
|
+
|
39
|
+
dirs
|
40
|
+
end
|
41
|
+
|
42
|
+
def english_languages
|
43
|
+
supported_languages.select do |lang|
|
44
|
+
lang =~ /^en/
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def javascript_include(filename)
|
49
|
+
unless filename =~ /^http/
|
50
|
+
filename = "#{@assets_directory}/javascripts/#{filename}"
|
51
|
+
end
|
52
|
+
"<script src='#{filename}' type='text/javascript' charset='utf-8'></script>"
|
53
|
+
end
|
54
|
+
|
55
|
+
def include_firebug_lite
|
56
|
+
javascript_include "http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js" if @domain != "my"
|
57
|
+
end
|
58
|
+
|
59
|
+
def render(params)
|
60
|
+
output = []
|
61
|
+
tags = true
|
62
|
+
if params[:tags] == false
|
63
|
+
tags = false
|
64
|
+
end
|
65
|
+
if params[:partial]
|
66
|
+
params[:partial].to_a.each do |partial|
|
67
|
+
output << render_partial(partial)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
if params[:javascript]
|
71
|
+
output << "<script type='text/javascript'>" if tags
|
72
|
+
output << render_javascripts(params[:javascript].to_a, params[:filename])
|
73
|
+
output << "</script>" if tags
|
74
|
+
end
|
75
|
+
if params[:stylesheet]
|
76
|
+
params[:stylesheet].to_a.each do |stylesheet|
|
77
|
+
output << render_stylesheet(stylesheet, tags)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
output.join("\n")
|
81
|
+
end
|
82
|
+
|
83
|
+
def render_partial(filename)
|
84
|
+
output = ''
|
85
|
+
path = nil
|
86
|
+
|
87
|
+
["views", "views/shared"].each do |dir|
|
88
|
+
basic_path = "#{BASE_PATH}/app/#{dir}/_#{filename}.html"
|
89
|
+
|
90
|
+
["", ".haml", ".erb"].each do |extension|
|
91
|
+
if File.exists?(basic_path + extension)
|
92
|
+
path ||= basic_path + extension
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
if path
|
98
|
+
|
99
|
+
File.open(path) do |f|
|
100
|
+
template = f.read
|
101
|
+
if path =~ /haml$/
|
102
|
+
output = process_haml(template, path)
|
103
|
+
else
|
104
|
+
output = process_template(template)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
else
|
108
|
+
raise "Could not find partial: #{filename}"
|
109
|
+
end
|
110
|
+
output
|
111
|
+
end
|
112
|
+
|
113
|
+
def render_stylesheet(filename, tags=false)
|
114
|
+
unless filename =~ /\.css$/
|
115
|
+
filename = "#{filename}.css"
|
116
|
+
end
|
117
|
+
path = "#{BASE_PATH}/app/stylesheets/#{filename}"
|
118
|
+
|
119
|
+
output = ''
|
120
|
+
if File.exists?(path)
|
121
|
+
tmp_filename = save_processed_template(path)
|
122
|
+
if compress_css?
|
123
|
+
output = ApplicationView::Compressor::Stylesheet.compress(tmp_filename)
|
124
|
+
else
|
125
|
+
File.open(path) do |f|
|
126
|
+
template = f.read
|
127
|
+
output = process_template(template)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
if tags
|
132
|
+
"<style type='text/css'>\n" + output + "\n</style>"
|
133
|
+
else
|
134
|
+
output
|
135
|
+
end
|
136
|
+
else
|
137
|
+
""
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def render_javascripts(filenames, combined_filename=nil)
|
142
|
+
output = []
|
143
|
+
|
144
|
+
# concatenate all javascript files into one long string
|
145
|
+
#
|
146
|
+
filenames.each do |filename|
|
147
|
+
output << render_without_compression(filename, false)
|
148
|
+
end
|
149
|
+
output = output.join("\n")
|
150
|
+
|
151
|
+
filenames_str = combined_filename || filenames.join()
|
152
|
+
tmp_filename = "./tmp/#{filenames_str}.js"
|
153
|
+
|
154
|
+
# use the saved file if it already exists
|
155
|
+
unless File.exists?(tmp_filename)
|
156
|
+
save_to_file(output, tmp_filename)
|
157
|
+
validate_filename = tmp_filename
|
158
|
+
end
|
159
|
+
|
160
|
+
# return compressed javascript or else don't
|
161
|
+
output = ApplicationView::Compressor::JavaScript.compress(tmp_filename) || output
|
162
|
+
|
163
|
+
ApplicationView::Validator::JavaScript.validate(validate_filename) if validate_filename
|
164
|
+
|
165
|
+
output
|
166
|
+
end
|
167
|
+
|
168
|
+
def render_without_compression(filename, tags=true)
|
169
|
+
unless filename =~ /\.js$/
|
170
|
+
filename = "#{filename}.js"
|
171
|
+
end
|
172
|
+
path = "#{YMDP_ROOT}/app/javascripts/#{filename}"
|
173
|
+
|
174
|
+
output = ''
|
175
|
+
|
176
|
+
if File.exists?(path)
|
177
|
+
File.open(path) do |f|
|
178
|
+
template = f.read
|
179
|
+
output = process_template(template)
|
180
|
+
end
|
181
|
+
|
182
|
+
if tags
|
183
|
+
"<script type='text/javascript'>\n" + output + "\n</script>"
|
184
|
+
else
|
185
|
+
output
|
186
|
+
end
|
187
|
+
else
|
188
|
+
""
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
# processes the template (with HAML or ERB) and saves it to the tmp folder
|
193
|
+
#
|
194
|
+
def save_processed_template(path)
|
195
|
+
filename = path.split("/").last
|
196
|
+
tmp_filename = "#{TMP_PATH}/#{filename}"
|
197
|
+
|
198
|
+
unless File.exists?(tmp_filename)
|
199
|
+
File.open(path) do |f|
|
200
|
+
template = f.read
|
201
|
+
output = process_template(template)
|
202
|
+
|
203
|
+
save_to_file(output, tmp_filename)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
tmp_filename
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require "#{APPLICATION_PATH}/tag_helper"
|
2
|
+
|
3
|
+
module ApplicationView
|
4
|
+
include ActionView::Helpers::TagHelper
|
5
|
+
|
6
|
+
ProtocolRegexp = %r{^[-a-z]+://}.freeze
|
7
|
+
|
8
|
+
module LinkTagHelper
|
9
|
+
def link_to_unless_current(text, url_or_view, options={});
|
10
|
+
if Application.current_view.downcase == url_or_view.downcase
|
11
|
+
text
|
12
|
+
else
|
13
|
+
link_to(text, url_or_view, options)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def link_to(text, url_or_view, options={})
|
18
|
+
if url_or_view =~ ProtocolRegexp
|
19
|
+
options[:href] = url_or_view
|
20
|
+
options[:target] ||= "_blank"
|
21
|
+
else
|
22
|
+
# this will create an in-YMDP link
|
23
|
+
options[:onclick] = "YAHOO.launcher.l('#{url_or_view}'); return false;"
|
24
|
+
options[:href] = "#"
|
25
|
+
end
|
26
|
+
content_tag("a", text, options)
|
27
|
+
end
|
28
|
+
|
29
|
+
def link_to_function(text, function, options={})
|
30
|
+
options[:onclick] = function
|
31
|
+
options[:href] = "#"
|
32
|
+
content_tag("a", text, options)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
module FormTagHelper
|
37
|
+
def text_field(name, options={})
|
38
|
+
options[:id] ||= name
|
39
|
+
options[:name] ||= name
|
40
|
+
options[:type] ||= "text"
|
41
|
+
|
42
|
+
tag("input", options)
|
43
|
+
end
|
44
|
+
|
45
|
+
def password_field(name, options={})
|
46
|
+
options[:type] = "password"
|
47
|
+
text_field(name, options)
|
48
|
+
end
|
49
|
+
|
50
|
+
def label(name, content_or_options = nil, options = {})
|
51
|
+
if content_or_options.is_a?(Hash)
|
52
|
+
options = content_or_options
|
53
|
+
text = name
|
54
|
+
else
|
55
|
+
text = content_or_options || name
|
56
|
+
end
|
57
|
+
options[:id] ||= "#{name.downcase}_label"
|
58
|
+
options[:for] ||= name.downcase
|
59
|
+
content_tag("label", text, options)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
module AssetTagHelper
|
64
|
+
|
65
|
+
def image_tag(source, options = {})
|
66
|
+
# options.symbolize_keys!
|
67
|
+
|
68
|
+
options[:src] = path_to_image(source)
|
69
|
+
options[:alt] ||= File.basename(options[:src], '.*').split('.').first.to_s.capitalize
|
70
|
+
|
71
|
+
if size = options.delete(:size)
|
72
|
+
options[:width], options[:height] = size.split("x") if size =~ %r{^\d+x\d+$}
|
73
|
+
end
|
74
|
+
|
75
|
+
if mouseover = options.delete(:mouseover)
|
76
|
+
options[:onmouseover] = "this.src='#{path_to_image(mouseover)}'"
|
77
|
+
options[:onmouseout] = "this.src='#{path_to_image(options[:src])}'"
|
78
|
+
end
|
79
|
+
|
80
|
+
tag("img", options)
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
# "funk" #=> "/om/assets/#{SERVERS[@domain]['assets_id']}/images/funk.png"
|
86
|
+
# "funk.jpg" #=> "/om/assets/#{SERVERS[@domain]['assets_id']}/images/funk.jpg"
|
87
|
+
# "/funky/chicken" #=> "/om/assets/#{SERVERS[@domain]['assets_id']}/funky/chicken.png"
|
88
|
+
# "funky/chicken" #=> "/om/assets/#{SERVERS[@domain]['assets_id']}/images/funky/chicken.png"
|
89
|
+
# "http://funk.com/chicken.jpg" #=> "http://funk.com/chicken.jpg"
|
90
|
+
#
|
91
|
+
def path_to_image(source)
|
92
|
+
unless source =~ /(\.jpg|\.png|\.gif)$/
|
93
|
+
source = "#{source}.png"
|
94
|
+
end
|
95
|
+
unless source =~ ProtocolRegexp
|
96
|
+
if source =~ /^\//
|
97
|
+
source = "#{@assets_directory}#{source}"
|
98
|
+
else
|
99
|
+
source = "#{@assets_directory}/images/#{source}"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
source
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|