tay 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +135 -0
- data/Rakefile +6 -0
- data/bin/tay +15 -0
- data/lib/tay.rb +19 -0
- data/lib/tay/builder.rb +173 -0
- data/lib/tay/cli.rb +29 -0
- data/lib/tay/cli/build.rb +15 -0
- data/lib/tay/cli/generate.rb +73 -0
- data/lib/tay/cli/generators/browser_action.rb +20 -0
- data/lib/tay/cli/generators/content_script.rb +37 -0
- data/lib/tay/cli/generators/page_action.rb +19 -0
- data/lib/tay/cli/generators/templates/browser_action/action.css +4 -0
- data/lib/tay/cli/generators/templates/browser_action/action.html +11 -0
- data/lib/tay/cli/generators/templates/browser_action/action.js +5 -0
- data/lib/tay/cli/generators/templates/browser_action/tayfile +7 -0
- data/lib/tay/cli/generators/templates/content_script/content_script.css +6 -0
- data/lib/tay/cli/generators/templates/content_script/content_script.js +4 -0
- data/lib/tay/cli/generators/templates/content_script/tayfile +6 -0
- data/lib/tay/cli/generators/templates/page_action/controller.js +7 -0
- data/lib/tay/cli/generators/templates/page_action/icon.png +0 -0
- data/lib/tay/cli/generators/templates/page_action/tayfile +7 -0
- data/lib/tay/cli/helpers.rb +51 -0
- data/lib/tay/cli/minify.rb +44 -0
- data/lib/tay/cli/new.rb +37 -0
- data/lib/tay/cli/package.rb +41 -0
- data/lib/tay/cli/templates/Gemfile +30 -0
- data/lib/tay/cli/templates/Tayfile +22 -0
- data/lib/tay/cli/templates/gitignore +5 -0
- data/lib/tay/cli/validate.rb +21 -0
- data/lib/tay/cli/watch.rb +29 -0
- data/lib/tay/manifest_generator.rb +160 -0
- data/lib/tay/packager.rb +64 -0
- data/lib/tay/specification.rb +261 -0
- data/lib/tay/specification/action.rb +18 -0
- data/lib/tay/specification/browser_action.rb +10 -0
- data/lib/tay/specification/content_script.rb +41 -0
- data/lib/tay/specification/nacl_module.rb +18 -0
- data/lib/tay/specification/packaged_app.rb +33 -0
- data/lib/tay/specification/page_action.rb +10 -0
- data/lib/tay/specification/web_intent.rb +40 -0
- data/lib/tay/specification_validator.rb +167 -0
- data/lib/tay/utils.rb +21 -0
- data/lib/tay/version.rb +3 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/tay_spec.rb +5 -0
- data/tay.gemspec +26 -0
- metadata +215 -0
@@ -0,0 +1,73 @@
|
|
1
|
+
module Tay
|
2
|
+
module CLI
|
3
|
+
class Generate < ::Thor
|
4
|
+
include ::Thor::Actions
|
5
|
+
include Tay::CLI::Helpers
|
6
|
+
|
7
|
+
class_option 'tayfile', :type => :string,
|
8
|
+
:banner => 'Use the specified tayfile instead of Tayfile'
|
9
|
+
class_option 'build-directory', :type => :string, :default => 'build',
|
10
|
+
:aliases => '-b', :banner => 'The directory containing the built extension'
|
11
|
+
|
12
|
+
def self.source_root
|
13
|
+
File.expand_path('generators/templates', File.dirname(__FILE__))
|
14
|
+
end
|
15
|
+
|
16
|
+
require 'tay/cli/generators/page_action'
|
17
|
+
require 'tay/cli/generators/browser_action'
|
18
|
+
require 'tay/cli/generators/content_script'
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
##
|
23
|
+
# Take some content and inject it inside the Tay::Specification
|
24
|
+
def inject_tayfile_content(new_content)
|
25
|
+
tayfile_contents = tayfile_path.read.strip
|
26
|
+
tayfile_contents.sub!(/end\Z/, "\n" + new_content + "\nend")
|
27
|
+
tayfile_path.open('w') do |f|
|
28
|
+
f.write(tayfile_contents)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# Render a template in the context of self and return its contents
|
34
|
+
# Thor does not provide a way to do this.
|
35
|
+
def render_template(path, locals = {})
|
36
|
+
tayfile_template = Tilt::ERBTemplate.new(find_in_source_paths(path), {
|
37
|
+
:trim => '-'
|
38
|
+
})
|
39
|
+
tayfile_template.render(self, locals)
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# Get path to src/assets
|
44
|
+
def asset_dir
|
45
|
+
src_dir.join('assets')
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Get path to src/html
|
50
|
+
def html_dir
|
51
|
+
src_dir.join('html')
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Get path to src/stylesheets
|
56
|
+
def stylesheet_dir
|
57
|
+
src_dir.join('stylesheets')
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# Get path to src/javascripts
|
62
|
+
def javascript_dir
|
63
|
+
src_dir.join('javascripts')
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# Get path to the src directory
|
68
|
+
def src_dir
|
69
|
+
tayfile_path.dirname.join('src')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Tay
|
2
|
+
module CLI
|
3
|
+
class Generate < ::Thor
|
4
|
+
desc "browser_action", "Generate a browser action"
|
5
|
+
method_option 'action-name', :type => :string, :default => 'Browser Action',
|
6
|
+
:aliases => '-n', :banner => 'The name of the browser action'
|
7
|
+
def browser_action
|
8
|
+
raise Tay::InvalidSpecification.new("Browser action already specified") if spec.browser_action
|
9
|
+
raise Tay::InvalidSpecification.new("You cannot have both browser and page actions") if spec.browser_action
|
10
|
+
raise Tay::InvalidSpecification.new("You cannot have both browser actions and packaged apps") if spec.packaged_app
|
11
|
+
|
12
|
+
fs_name = Utils.filesystem_name(options['action-name'])
|
13
|
+
copy_file('browser_action/action.js', javascript_dir.join(fs_name+ '.js'))
|
14
|
+
copy_file('browser_action/action.css', stylesheet_dir.join(fs_name+ '.css'))
|
15
|
+
create_file(html_dir.join(fs_name+ '.html'), render_template('browser_action/action.html', :fs_name => fs_name))
|
16
|
+
inject_tayfile_content(render_template('browser_action/tayfile', :fs_name => fs_name))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Tay
|
2
|
+
module CLI
|
3
|
+
class Generate < ::Thor
|
4
|
+
desc "content_script", "Generate a content script"
|
5
|
+
def content_script
|
6
|
+
copy_file('content_script/content_script.js', javascript_dir.join('content_script.js'))
|
7
|
+
copy_file('content_script/content_script.css', stylesheet_dir.join('content_script.css'))
|
8
|
+
inject_tayfile_content(File.read(find_in_source_paths('content_script/tayfile_content')))
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module Tay
|
15
|
+
module CLI
|
16
|
+
class Generate < ::Thor
|
17
|
+
desc "content_script", "Generate a content script"
|
18
|
+
method_option 'script-name', :type => :string, :default => 'content_script',
|
19
|
+
:aliases => '-n', :banner => 'The name of the content script'
|
20
|
+
method_option 'no-javascript', :type => :boolean, :default => false,
|
21
|
+
:banner => "Don\'t create a javascript file"
|
22
|
+
method_option 'no-stylesheet', :type => :boolean, :default => false,
|
23
|
+
:banner => "Don\'t create a stylesheet"
|
24
|
+
def content_script
|
25
|
+
fs_name = Utils.filesystem_name(options['script-name'])
|
26
|
+
|
27
|
+
unless options['no-javascript']
|
28
|
+
copy_file('content_script/content_script.js', javascript_dir.join(fs_name + '.js'))
|
29
|
+
end
|
30
|
+
unless options['no-stylesheet']
|
31
|
+
copy_file('content_script/content_script.css', stylesheet_dir.join(fs_name + '.css'))
|
32
|
+
end
|
33
|
+
inject_tayfile_content(render_template('content_script/tayfile', :fs_name => fs_name))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Tay
|
2
|
+
module CLI
|
3
|
+
class Generate < ::Thor
|
4
|
+
desc "page_action", "Generate a page action"
|
5
|
+
method_option 'action-name', :type => :string, :default => 'Page Action',
|
6
|
+
:aliases => '-n', :banner => 'The name of the page action'
|
7
|
+
def page_action
|
8
|
+
raise Tay::InvalidSpecification.new("Page action already specified") if spec.page_action
|
9
|
+
raise Tay::InvalidSpecification.new("You cannot have both page and browser actions") if spec.browser_action
|
10
|
+
raise Tay::InvalidSpecification.new("You cannot have both page actions and packaged apps") if spec.packaged_app
|
11
|
+
|
12
|
+
fs_name = Utils.filesystem_name(options['action-name'])
|
13
|
+
copy_file('page_action/icon.png', asset_dir.join(fs_name + '_icon.png'))
|
14
|
+
copy_file('page_action/controller.js', javascript_dir.join(fs_name + '_controller.js'))
|
15
|
+
inject_tayfile_content(render_template('page_action/tayfile', :fs_name => fs_name))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title><%= options['action-name'] %></title>
|
5
|
+
<script src="/javascripts/<%= fs_name %>.js"></script>
|
6
|
+
<link rel="stylesheet" type="text/css" href="/stylesheets/<%= fs_name %>.css">
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<h1>Hello World!</h1>
|
10
|
+
</body>
|
11
|
+
</html>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
ext.stylesheets << 'stylesheets/<%= fs_name %>.css'
|
2
|
+
ext.javascripts << 'javascripts/<%= fs_name %>.js'
|
3
|
+
ext.add_browser_action do |ba|
|
4
|
+
ba.title = '<%= options['action-name'] %>'
|
5
|
+
ba.popup = 'html/<%= fs_name %>.html'
|
6
|
+
# ba.icon = 'assets/<%= fs_name %>_icon.png'
|
7
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
# Go to http://www.iana.org/domains/example/ to see the effects
|
2
|
+
ext.add_content_script do |cs|
|
3
|
+
cs.include_patterns << 'http://www.iana.org/domains/*'
|
4
|
+
<%= " cs.stylesheets << 'stylesheets/#{fs_name}.css'\n" unless options['no-stylesheet'] -%>
|
5
|
+
<%= " cs.javascripts << 'javascripts/#{fs_name}.js'\n" unless options['no-javascript'] -%>
|
6
|
+
end
|
Binary file
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<%= " ext.permissions << 'tabs'\n" unless spec.has_permission?('tabs') -%>
|
2
|
+
ext.background_scripts << 'javascripts/<%= fs_name %>_controller.js'
|
3
|
+
ext.add_page_action do |pa|
|
4
|
+
pa.title = '<%= options['action-name'] %>'
|
5
|
+
pa.icon = 'assets/<%= fs_name %>_icon.png'
|
6
|
+
# pa.popup = 'html/<%= fs_name %>_popup.html'
|
7
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Tay
|
2
|
+
module CLI
|
3
|
+
module Helpers
|
4
|
+
DEFAULT_TAYFILE = 'Tayfile'
|
5
|
+
|
6
|
+
protected
|
7
|
+
|
8
|
+
def spec
|
9
|
+
@spec ||= get_specification
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_specification(path = nil)
|
13
|
+
path = path ? Pathname.new(path) : tayfile_path
|
14
|
+
|
15
|
+
unless path.exist?
|
16
|
+
if options['tayfile'].nil?
|
17
|
+
message = "No Tayfile was found in the current directory"
|
18
|
+
else
|
19
|
+
message = "#{path} does not exist"
|
20
|
+
end
|
21
|
+
raise SpecificationNotFound.new(message)
|
22
|
+
end
|
23
|
+
|
24
|
+
eval(File.open(path).read)
|
25
|
+
end
|
26
|
+
|
27
|
+
def tayfile_path
|
28
|
+
Pathname.new(options['tayfile'] || DEFAULT_TAYFILE).expand_path
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Return the base directory for this extension
|
33
|
+
def base_dir
|
34
|
+
tayfile_path.dirname
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# Return the src directory for this extension
|
39
|
+
def src_dir
|
40
|
+
base_dir.join('src')
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Return the build directory for this extension, respecting any command
|
45
|
+
# line option
|
46
|
+
def build_dir
|
47
|
+
base_dir.join(options['build-directory'] || 'build')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Tay
|
2
|
+
module CLI
|
3
|
+
class Root < ::Thor
|
4
|
+
desc 'minify', 'Minify the CSS and JS of the currently built extension'
|
5
|
+
method_option 'tayfile', :type => :string,
|
6
|
+
:banner => 'Use the specified tayfile instead of Tayfile'
|
7
|
+
method_option 'build-directory', :type => :string, :default => 'build',
|
8
|
+
:aliases => '-b', :banner => 'The directory containing the built extension'
|
9
|
+
method_option 'skip-js', :type => :boolean, :default => false,
|
10
|
+
:banner => "Don't minify *.js files"
|
11
|
+
method_option 'skip-css', :type => :boolean, :default => false,
|
12
|
+
:banner => "Don't minify *.css files"
|
13
|
+
def minify
|
14
|
+
unless options['skip-js']
|
15
|
+
begin
|
16
|
+
require 'uglifier'
|
17
|
+
Dir[build_dir.join('**/*.js')].each do |path|
|
18
|
+
content = File.read(path)
|
19
|
+
File.open(path, 'w') do |f|
|
20
|
+
f.write Uglifier.compile(content)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
rescue LoadError
|
24
|
+
say('ERROR: please add the uglifier gem to your Gemfile to minfy javascripts', :red)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
unless options['skip-css']
|
29
|
+
begin
|
30
|
+
require 'yui/compressor'
|
31
|
+
Dir[build_dir.join('**/*.css')].each do |path|
|
32
|
+
content = File.read(path)
|
33
|
+
File.open(path, 'w') do |f|
|
34
|
+
f.write YUI::CssCompressor.new.compress(content)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
rescue LoadError
|
38
|
+
say('ERROR: please add the yui-compressor gem to your Gemfile to minfy css files', :red)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/tay/cli/new.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module Tay
|
2
|
+
module CLI
|
3
|
+
class Root < ::Thor
|
4
|
+
desc 'new NAME', 'Create a new extension'
|
5
|
+
method_option 'no-gitignore', :type => :boolean, :default => false,
|
6
|
+
:banner => "Don\'t create a .gitignore file"
|
7
|
+
method_option 'no-gemfile', :type => :boolean, :default => false,
|
8
|
+
:banner => "Don\'t create a Gemfile file"
|
9
|
+
method_option 'use-coffeescript', :type => :boolean, :default => false,
|
10
|
+
:banner => "Use coffeescript"
|
11
|
+
method_option 'use-haml', :type => :boolean, :default => false,
|
12
|
+
:banner => "Use haml"
|
13
|
+
def new(name)
|
14
|
+
outdir = Pathname.new(Utils.filesystem_name(name))
|
15
|
+
create_directory_structure(outdir)
|
16
|
+
|
17
|
+
template('Gemfile', outdir.join('Gemfile')) unless options['no-gemfile']
|
18
|
+
copy_file('gitignore', outdir.join('.gitignore')) unless options['no-gitignore']
|
19
|
+
template('Tayfile', outdir.join('Tayfile'), {
|
20
|
+
'name' => name
|
21
|
+
}.merge(options))
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def create_directory_structure(outdir)
|
27
|
+
empty_directory(outdir)
|
28
|
+
empty_directory(outdir.join('src'))
|
29
|
+
empty_directory(outdir.join('src/assets'))
|
30
|
+
empty_directory(outdir.join('src/html'))
|
31
|
+
empty_directory(outdir.join('src/javascripts'))
|
32
|
+
empty_directory(outdir.join('src/stylesheets'))
|
33
|
+
empty_directory(outdir.join('src/templates'))
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Tay
|
2
|
+
module CLI
|
3
|
+
class Root < ::Thor
|
4
|
+
desc 'package', 'Package the current extension'
|
5
|
+
method_option 'tayfile', :type => :string,
|
6
|
+
:banner => 'Use the specified tayfile instead of Tayfile'
|
7
|
+
method_option 'build-directory', :type => :string, :default => 'build',
|
8
|
+
:aliases => '-b', :banner => 'The directory containing the built extension'
|
9
|
+
method_option 'type', :type => 'string', :default => 'zip',
|
10
|
+
:aliases => '-t', :banner => 'The file type to build, zip or crx'
|
11
|
+
def package
|
12
|
+
unless %{zip crx} .include?(options['type'])
|
13
|
+
raise InvalidPackageType.new("Invalid package type '#{options['type']}'")
|
14
|
+
end
|
15
|
+
|
16
|
+
packager = Packager.new(spec, base_dir, build_dir)
|
17
|
+
|
18
|
+
if packager.private_key_exists?
|
19
|
+
say("Using private key at #{Utils.relative_path_to(packager.full_key_path)}", :green)
|
20
|
+
else
|
21
|
+
say("Creating private key at #{Utils.relative_path_to(packager.full_key_path)}", :yellow)
|
22
|
+
packager.write_new_key
|
23
|
+
end
|
24
|
+
|
25
|
+
empty_directory(base_dir.join('tmp'))
|
26
|
+
empty_directory(base_dir.join('pkg'))
|
27
|
+
|
28
|
+
temp_pkg_path = base_dir.join('tmp', 'package')
|
29
|
+
temp_pkg_path.unlink if temp_pkg_path.exist?
|
30
|
+
packager.send("write_#{options['type']}".to_sym, temp_pkg_path)
|
31
|
+
|
32
|
+
filename = Utils.filesystem_name(spec.name) + '-' + spec.version + '.' + options['type']
|
33
|
+
pkg_path = base_dir.join('pkg', filename)
|
34
|
+
|
35
|
+
copy_file(temp_pkg_path, pkg_path)
|
36
|
+
say("Wrote #{pkg_path.size} bytes to #{Utils.relative_path_to(pkg_path)}", :green)
|
37
|
+
temp_pkg_path.unlink
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'tay'
|
4
|
+
|
5
|
+
# You can make extensions with no extra gems, but tay works best when
|
6
|
+
# coupled with other langauges and tools. Uncomment them gems below
|
7
|
+
# then run "bundle install"
|
8
|
+
|
9
|
+
# Allows you to run "tay watch" to automatically recompile on change
|
10
|
+
# gem 'guard-tay'
|
11
|
+
|
12
|
+
<%= options['use-haml'] ? '' : '# ' %>gem 'haml'
|
13
|
+
# gem 'sass'
|
14
|
+
<%= options['use-coffeescript'] ? '' : '# ' %>gem 'coffee-script'
|
15
|
+
|
16
|
+
# Enable the usage .jst.mustache templates via Sprockets
|
17
|
+
# gem 'mustache-trimmer', :git => 'git://github.com/josh/mustache-trimmer.git'
|
18
|
+
|
19
|
+
# Enable the usage .jst.eco templates via Sprockets
|
20
|
+
# gem 'eco'
|
21
|
+
|
22
|
+
# Allows you to use CommonJS requires in your script files
|
23
|
+
# See https://github.com/maccman/sprockets-commonjs
|
24
|
+
# gem 'sprockets-commonjs', '0.0.5.pre', :require => 'sprockets/commonjs'
|
25
|
+
|
26
|
+
# Enable javascript compression via "tay minify"
|
27
|
+
# gem 'uglifier'
|
28
|
+
|
29
|
+
# Enable css compression via "tay minify"
|
30
|
+
# gem 'yui-compressor'
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Tay::Specification.new do |ext|
|
2
|
+
ext.name = '<%= config['name'] %>'
|
3
|
+
ext.version = '0.0.1'
|
4
|
+
<% if config['browser-action'] %>
|
5
|
+
ext.stylesheets << 'stylesheets/browser_action.css'
|
6
|
+
ext.javascripts << 'javascripts/browser_action.js'
|
7
|
+
ext.add_browser_action do |ba|
|
8
|
+
ba.title = '<%= config['name'] %>'
|
9
|
+
ba.popup = 'html/browser_action.html'
|
10
|
+
# ba.icon = 'assets/browser_action_icon.png'
|
11
|
+
end
|
12
|
+
<% end -%>
|
13
|
+
<% if config['page-action'] %>
|
14
|
+
ext.permissions << 'tabs'
|
15
|
+
ext.background_scripts << 'javascripts/page_action_controller.js'
|
16
|
+
ext.add_page_action do |pa|
|
17
|
+
pa.title = '<%= config['name'] %>'
|
18
|
+
pa.icon = 'assets/page_action_icon.png'
|
19
|
+
# pa.popup = 'html/page_action.html'
|
20
|
+
end
|
21
|
+
<% end -%>
|
22
|
+
end
|