tay 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/.gitignore +18 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +22 -0
  4. data/README.md +135 -0
  5. data/Rakefile +6 -0
  6. data/bin/tay +15 -0
  7. data/lib/tay.rb +19 -0
  8. data/lib/tay/builder.rb +173 -0
  9. data/lib/tay/cli.rb +29 -0
  10. data/lib/tay/cli/build.rb +15 -0
  11. data/lib/tay/cli/generate.rb +73 -0
  12. data/lib/tay/cli/generators/browser_action.rb +20 -0
  13. data/lib/tay/cli/generators/content_script.rb +37 -0
  14. data/lib/tay/cli/generators/page_action.rb +19 -0
  15. data/lib/tay/cli/generators/templates/browser_action/action.css +4 -0
  16. data/lib/tay/cli/generators/templates/browser_action/action.html +11 -0
  17. data/lib/tay/cli/generators/templates/browser_action/action.js +5 -0
  18. data/lib/tay/cli/generators/templates/browser_action/tayfile +7 -0
  19. data/lib/tay/cli/generators/templates/content_script/content_script.css +6 -0
  20. data/lib/tay/cli/generators/templates/content_script/content_script.js +4 -0
  21. data/lib/tay/cli/generators/templates/content_script/tayfile +6 -0
  22. data/lib/tay/cli/generators/templates/page_action/controller.js +7 -0
  23. data/lib/tay/cli/generators/templates/page_action/icon.png +0 -0
  24. data/lib/tay/cli/generators/templates/page_action/tayfile +7 -0
  25. data/lib/tay/cli/helpers.rb +51 -0
  26. data/lib/tay/cli/minify.rb +44 -0
  27. data/lib/tay/cli/new.rb +37 -0
  28. data/lib/tay/cli/package.rb +41 -0
  29. data/lib/tay/cli/templates/Gemfile +30 -0
  30. data/lib/tay/cli/templates/Tayfile +22 -0
  31. data/lib/tay/cli/templates/gitignore +5 -0
  32. data/lib/tay/cli/validate.rb +21 -0
  33. data/lib/tay/cli/watch.rb +29 -0
  34. data/lib/tay/manifest_generator.rb +160 -0
  35. data/lib/tay/packager.rb +64 -0
  36. data/lib/tay/specification.rb +261 -0
  37. data/lib/tay/specification/action.rb +18 -0
  38. data/lib/tay/specification/browser_action.rb +10 -0
  39. data/lib/tay/specification/content_script.rb +41 -0
  40. data/lib/tay/specification/nacl_module.rb +18 -0
  41. data/lib/tay/specification/packaged_app.rb +33 -0
  42. data/lib/tay/specification/page_action.rb +10 -0
  43. data/lib/tay/specification/web_intent.rb +40 -0
  44. data/lib/tay/specification_validator.rb +167 -0
  45. data/lib/tay/utils.rb +21 -0
  46. data/lib/tay/version.rb +3 -0
  47. data/spec/spec_helper.rb +4 -0
  48. data/spec/tay_spec.rb +5 -0
  49. data/tay.gemspec +26 -0
  50. metadata +215 -0
@@ -0,0 +1,18 @@
1
+ module Tay
2
+ class Specification
3
+ ##
4
+ # Action is a parent class shared between Tay::Specification::PageAction
5
+ # and Tay::Specification::BrowserAction.
6
+ class Action
7
+ ##
8
+ # Path to the icon that is displayed in the browser
9
+ attr_accessor :icon
10
+ ##
11
+ # Title that appears on mouseover
12
+ attr_accessor :title
13
+ ##
14
+ # Path to the HTML file that is displayed when your action is clicked
15
+ attr_accessor :popup
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,10 @@
1
+ module Tay
2
+ class Specification
3
+ ##
4
+ # Represents a browser action in your extension
5
+ #
6
+ # http://code.google.com/chrome/extensions/browserAction.html
7
+ class BrowserAction < Action
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,41 @@
1
+ module Tay
2
+ class Specification
3
+ ##
4
+ # Represents a content script in your extension. For more information on
5
+ # valid values for attributes and pattern specications, check the docs.
6
+ #
7
+ # http://code.google.com/chrome/extensions/content_scripts.html
8
+ class ContentScript
9
+ ##
10
+ # Specifies when to inject and run this content script.
11
+ attr_accessor :run_at
12
+
13
+ ##
14
+ # Should this content script run in every frame on a page?
15
+ attr_accessor :all_frames
16
+
17
+ ##
18
+ # An array of patterns to include this content script on
19
+ attr_accessor :include_patterns
20
+
21
+ ##
22
+ # An array of patterns to exclude this content script on
23
+ attr_accessor :exclude_patterns
24
+
25
+ ##
26
+ # An array of stylesheet paths to inject
27
+ attr_accessor :stylesheets
28
+
29
+ ##
30
+ # An array of script paths to inject
31
+ attr_accessor :javascripts
32
+
33
+ def initialize
34
+ @include_patterns = []
35
+ @exclude_patterns = []
36
+ @javascripts = []
37
+ @stylesheets = []
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,18 @@
1
+ module Tay
2
+ class Specification
3
+ ##
4
+ # Used to map a mime-type to a native client module
5
+ #
6
+ # * http://code.google.com/chrome/extensions/manifest.html#nacl_modules
7
+ # * http://code.google.com/chrome/nativeclient/docs/technical_overview.html
8
+ class NaClModule
9
+ ##
10
+ # Path to the .nmf file for your module
11
+ attr_accessor :path
12
+
13
+ ##
14
+ # The mime-type that will load your module
15
+ attr_accessor :mime_type
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,33 @@
1
+ module Tay
2
+ class Specification
3
+ ##
4
+ # A packaged app is included on the user's New Tab screen. They cannot have
5
+ # page or browser actions.
6
+ #
7
+ # http://code.google.com/chrome/extensions/apps.html
8
+ class PackagedApp
9
+ ##
10
+ # When your app is launched, this is the path to the HTML file that will
11
+ # be loaded
12
+ attr_accessor :page
13
+
14
+ attr_reader :container
15
+ attr_reader :width, :height
16
+
17
+ ##
18
+ # If you app should appear in its own panel, call this method, supplying
19
+ # the width and height of said panel
20
+ def appears_in_panel(width, height)
21
+ @container = 'panel'
22
+ @width = width
23
+ @height = height
24
+ end
25
+
26
+ ##
27
+ # If you app should appear in a standard tab (default) call this method.
28
+ def appears_in_tab
29
+ @container = 'tab'
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,10 @@
1
+ module Tay
2
+ class Specification
3
+ ##
4
+ # Represents a page action in your extension
5
+ #
6
+ # http://code.google.com/chrome/extensions/pageAction.html
7
+ class PageAction < Action
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,40 @@
1
+ module Tay
2
+ class Specification
3
+ ##
4
+ # Represents a web intent that your extension provides. For more info
5
+ # check the Google Chrome extension docs, and spec at the URLs below.
6
+ #
7
+ # * http://code.google.com/chrome/extensions/manifest.html#intents
8
+ # * http://www.webintents.org/
9
+ class WebIntent
10
+ ##
11
+ # The "title" is displayed in the intent picker UI when the user
12
+ # initiates the action specific to the handler.
13
+ attr_accessor :action
14
+
15
+ ##
16
+ # The "title" is displayed in the intent picker UI when the user
17
+ # initiates the action specific to the handler.
18
+ attr_accessor :title
19
+
20
+ ##
21
+ # The "title" is displayed in the intent picker UI when the user
22
+ # initiates the action specific to the handler.
23
+ attr_accessor :href
24
+
25
+ ##
26
+ # Intents with "window" disposition will open a new tab when invoked,
27
+ # those with "inline" disposition will be displayed inside the intent
28
+ # picker when invoked.
29
+ attr_accessor :disposition
30
+
31
+ ##
32
+ # An array of mime types that your intent can act upon
33
+ attr_accessor :types
34
+
35
+ def initialize
36
+ @types = []
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,167 @@
1
+ module Tay
2
+ ##
3
+ # Takes a Tay::Specification and does sanity checks for missing required
4
+ # fields. It also looks for common mistakes and mutually exclusive flags.
5
+ #
6
+ # If the output directory is supplied (referencing the compiled extension),
7
+ # the existence of files referenced in the specification will also be checked
8
+ # for their presence.
9
+ class SpecificationValidator
10
+ ##
11
+ # Pointer to the relevant Tay::Specification
12
+ attr_reader :spec
13
+
14
+ ##
15
+ # If true (default) throw an exception on error
16
+ attr_accessor :violent
17
+
18
+ ##
19
+ # A proc object that will be called on each message with the type and msg
20
+ attr_accessor :on_message
21
+
22
+ attr_reader :warnings
23
+ attr_reader :errors
24
+
25
+ ##
26
+ # Convenience method to validate a specification. Creates a validator and
27
+ # runs it. Will throw an exception if invalid.
28
+ def self.validate(specification, output_directory = nil)
29
+ validator = SpecificationValidator.new(specification, output_directory)
30
+ validator.violent = true
31
+ validator.validate!
32
+ end
33
+
34
+ def initialize(specification, output_directory = nil)
35
+ @spec = specification
36
+ @out = output_directory ? Pathname.new(output_directory) : nil
37
+ @errors = []
38
+ @warnings = []
39
+ end
40
+
41
+ ##
42
+ # Facade method to call the private validation methods. Will return true if
43
+ # there were no warnings or errors
44
+ def validate!
45
+ validate_name
46
+ validate_version
47
+ validate_icons
48
+ validate_description
49
+
50
+ check_for_browser_ui_collisions
51
+
52
+ check_file_presence if @out
53
+
54
+ @warnings.empty? && @errors.empty?
55
+ end
56
+
57
+ protected
58
+
59
+ ##
60
+ # Go through the specification checking that files that are pointed to
61
+ # actually exist
62
+ def check_file_presence
63
+ spec.icons.values.each do |path|
64
+ fail_if_not_exist "Icon", path
65
+ end
66
+
67
+ if spec.browser_action
68
+ fail_if_not_exist "Browser action popup", spec.browser_action.popup
69
+ fail_if_not_exist "Browser action icon", spec.browser_action.icon
70
+ end
71
+
72
+ if spec.page_action
73
+ fail_if_not_exist "Page action popup", spec.page_action.popup
74
+ fail_if_not_exist "Page action icon", spec.page_action.icon
75
+ end
76
+
77
+ if spec.packaged_app
78
+ fail_if_not_exist "App launch page", spec.packaged_app.page
79
+ end
80
+
81
+ spec.content_scripts.each do |content_script|
82
+ content_script.javascripts.each do |script_path|
83
+ fail_if_not_exist "Content script javascript", script_path
84
+ end
85
+ content_script.stylesheets.each do |style_path|
86
+ fail_if_not_exist "Content script style", style_path
87
+ end
88
+ end
89
+
90
+ spec.background_scripts.each do |script_path|
91
+ fail_if_not_exist "Background script style", script_path
92
+ end
93
+
94
+ fail_if_not_exist "Background page", spec.background_page
95
+ fail_if_not_exist "Options page", spec.options_page
96
+
97
+ spec.web_intents.each do |web_intent|
98
+ fail_if_not_exist "Web intent href", web_intent.href
99
+ end
100
+
101
+ spec.nacl_modules.each do |nacl_module|
102
+ fail_if_not_exist "NaCl module", nacl_module.path
103
+ end
104
+
105
+ spec.web_accessible_resources.each do |path|
106
+ fail_if_not_exist "Web accessible resource", path
107
+ end
108
+ end
109
+
110
+ def validate_name
111
+ fatal("No name provided") unless spec.name
112
+ fatal("Name too long") if spec.name.length > 45
113
+ end
114
+
115
+ def validate_version
116
+ fatal("No version provided") unless spec.version
117
+ fatal("Invalid characters in version") if spec.version[/[^0-9\.]/]
118
+ end
119
+
120
+ def validate_icons
121
+ warn("No icons provided") if spec.icons.keys.empty?
122
+ end
123
+
124
+ def validate_description
125
+ fatal("Description too long") if spec.description && spec.description.length > 132
126
+ end
127
+
128
+ def check_for_browser_ui_collisions
129
+ count = 0
130
+ count += 1 if spec.packaged_app
131
+ count += 1 if spec.page_action
132
+ count += 1 if spec.browser_action
133
+
134
+ if count > 1
135
+ fatal('Only one of browser_action, page_action, and packaged app can be specified')
136
+ end
137
+ end
138
+
139
+ def check_for_background_collisions
140
+ if spec.background_page && spec.background_scripts.length > 0
141
+ fatal("You cannot use both background pages and background scripts")
142
+ end
143
+ end
144
+
145
+ private
146
+
147
+ def fatal(msg)
148
+ @errors << msg
149
+ unless on_message.nil?
150
+ on_message.call('fatal', msg)
151
+ end
152
+ raise Tay::InvalidSpecification.new if violent
153
+ end
154
+
155
+ def warn(msg)
156
+ @warnings << msg
157
+ unless on_message.nil?
158
+ on_message.call('warn', msg)
159
+ end
160
+ end
161
+
162
+ def fail_if_not_exist(what, path)
163
+ fatal("#{what} does not exist at '#{path}'") unless !path || @out.join(path).exist?
164
+ end
165
+ end
166
+
167
+ end
@@ -0,0 +1,21 @@
1
+ module Tay
2
+ ##
3
+ # Simple helpers used across various classes
4
+ class Utils
5
+ ##
6
+ # Convert an extension name to a filesystem friendly name
7
+ def self.filesystem_name(name)
8
+ name.gsub(/[^a-zA-Z0-9\-_ ]/, '').gsub(/ /, '_').downcase
9
+ end
10
+
11
+ ##
12
+ # Convert a path to be relative to pwd
13
+ def self.relative_path_to(path)
14
+ if path.is_a?(String)
15
+ path = Pathname.new(path)
16
+ end
17
+ path.relative_path_from(Pathname.new(Dir.pwd))
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ module Tay
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,4 @@
1
+ $:.unshift(File.expand_path('../../lib', __FILE__))
2
+
3
+ require 'rspec'
4
+ require 'tay'
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Tay do
4
+ specify { Tay.should be_a(Module) }
5
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/tay/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Thomas Rix"]
6
+ gem.email = ["tom@rixth.org"]
7
+ gem.summary = %q{Tay helps you develop Chrome extensions}
8
+ gem.description = gem.summary
9
+ gem.homepage = "https://github.com/rixth/tay"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "tay"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Tay::VERSION
17
+
18
+ gem.add_dependency 'thor'
19
+ gem.add_dependency 'tilt'
20
+ gem.add_dependency 'sprockets'
21
+ gem.add_dependency 'crxmake'
22
+
23
+ gem.add_development_dependency 'rspec'
24
+ gem.add_development_dependency 'sdoc'
25
+ gem.add_development_dependency 'rake'
26
+ end
metadata ADDED
@@ -0,0 +1,215 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tay
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Thomas Rix
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: thor
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: tilt
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: sprockets
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: crxmake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: sdoc
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: rake
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ description: Tay helps you develop Chrome extensions
127
+ email:
128
+ - tom@rixth.org
129
+ executables:
130
+ - tay
131
+ extensions: []
132
+ extra_rdoc_files: []
133
+ files:
134
+ - .gitignore
135
+ - Gemfile
136
+ - LICENSE
137
+ - README.md
138
+ - Rakefile
139
+ - bin/tay
140
+ - lib/tay.rb
141
+ - lib/tay/builder.rb
142
+ - lib/tay/cli.rb
143
+ - lib/tay/cli/build.rb
144
+ - lib/tay/cli/generate.rb
145
+ - lib/tay/cli/generators/browser_action.rb
146
+ - lib/tay/cli/generators/content_script.rb
147
+ - lib/tay/cli/generators/page_action.rb
148
+ - lib/tay/cli/generators/templates/browser_action/action.css
149
+ - lib/tay/cli/generators/templates/browser_action/action.html
150
+ - lib/tay/cli/generators/templates/browser_action/action.js
151
+ - lib/tay/cli/generators/templates/browser_action/tayfile
152
+ - lib/tay/cli/generators/templates/content_script/content_script.css
153
+ - lib/tay/cli/generators/templates/content_script/content_script.js
154
+ - lib/tay/cli/generators/templates/content_script/tayfile
155
+ - lib/tay/cli/generators/templates/page_action/controller.js
156
+ - lib/tay/cli/generators/templates/page_action/icon.png
157
+ - lib/tay/cli/generators/templates/page_action/tayfile
158
+ - lib/tay/cli/helpers.rb
159
+ - lib/tay/cli/minify.rb
160
+ - lib/tay/cli/new.rb
161
+ - lib/tay/cli/package.rb
162
+ - lib/tay/cli/templates/Gemfile
163
+ - lib/tay/cli/templates/Tayfile
164
+ - lib/tay/cli/templates/gitignore
165
+ - lib/tay/cli/validate.rb
166
+ - lib/tay/cli/watch.rb
167
+ - lib/tay/manifest_generator.rb
168
+ - lib/tay/packager.rb
169
+ - lib/tay/specification.rb
170
+ - lib/tay/specification/action.rb
171
+ - lib/tay/specification/browser_action.rb
172
+ - lib/tay/specification/content_script.rb
173
+ - lib/tay/specification/nacl_module.rb
174
+ - lib/tay/specification/packaged_app.rb
175
+ - lib/tay/specification/page_action.rb
176
+ - lib/tay/specification/web_intent.rb
177
+ - lib/tay/specification_validator.rb
178
+ - lib/tay/utils.rb
179
+ - lib/tay/version.rb
180
+ - spec/spec_helper.rb
181
+ - spec/tay_spec.rb
182
+ - tay.gemspec
183
+ homepage: https://github.com/rixth/tay
184
+ licenses: []
185
+ post_install_message:
186
+ rdoc_options: []
187
+ require_paths:
188
+ - lib
189
+ required_ruby_version: !ruby/object:Gem::Requirement
190
+ none: false
191
+ requirements:
192
+ - - ! '>='
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ segments:
196
+ - 0
197
+ hash: -81594321510644905
198
+ required_rubygems_version: !ruby/object:Gem::Requirement
199
+ none: false
200
+ requirements:
201
+ - - ! '>='
202
+ - !ruby/object:Gem::Version
203
+ version: '0'
204
+ segments:
205
+ - 0
206
+ hash: -81594321510644905
207
+ requirements: []
208
+ rubyforge_project:
209
+ rubygems_version: 1.8.24
210
+ signing_key:
211
+ specification_version: 3
212
+ summary: Tay helps you develop Chrome extensions
213
+ test_files:
214
+ - spec/spec_helper.rb
215
+ - spec/tay_spec.rb