tay 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -16,3 +16,5 @@ spec/reports
16
16
  test/tmp
17
17
  test/version_tmp
18
18
  tmp
19
+ lib/tay/cli/generators/templates/**/*.html
20
+ lib/tay/cli/generators/templates/**/*.js
data/README.md CHANGED
@@ -2,10 +2,22 @@
2
2
 
3
3
  Tay is designed to help you swiftly write Google Chrome extensions using your favourite languages and tools.
4
4
 
5
+ ## Quickstart
6
+
7
+ $ gem install tay
8
+ $ tay new my_extension
9
+ $ cd my_extension
10
+ $ tay generate browser_action
11
+ $ tay build
12
+
13
+ Now go and load your extension in Chrome and look in the top right for the puzzle piece!
14
+
5
15
  ## Installation
6
16
 
7
17
  $ gem install tay
8
18
 
19
+ If installing the gem from source, be sure to run `rake build_generators` first!
20
+
9
21
  ## Usage
10
22
 
11
23
  Tay helps create, bootstrap, develop and publish Chrome extentions. It all works through the `tay` command. Running `tay` alone will show you a list of commands.
@@ -71,7 +83,7 @@ To build the extension, run `tay build`. Source files will be compiled and writt
71
83
 
72
84
  If you run `tay watch` in the top level directory, tay will automatically build whenever a change is detected in the `src` directory *(you still need to go and reload the unpacked extension in Chrome)*.
73
85
 
74
- To use `tay watch` you'll need to add the `[guard-tay](http://github.com/rixth/guard-tay` gem to your Gemfile and run `bundle install`. If you want to customize the directories that are watched for changes, you can generate a [Guardfile](http://github.com/guard/guard) by running `guard init tay`.
86
+ To use `tay watch` you'll need to add the [guard-tay](http://github.com/rixth/guard-tay) gem to your Gemfile and run `bundle install`. If you want to customize the directories that are watched for changes, you can generate a [Guardfile](http://github.com/guard/guard) by running `guard init tay`.
75
87
 
76
88
  Usage:
77
89
  tay watch
@@ -85,7 +97,7 @@ To use `tay watch` you'll need to add the `[guard-tay](http://github.com/rixth/g
85
97
 
86
98
  ### Minifying
87
99
 
88
- If you have the `[uglifier](https://github.com/lautis/uglifier)` and/or `[yui-compressor](https://github.com/sstephenson/ruby-yui-compressor)` gems in your Gemfile, you will be able to minify the JS and CSS in a built extension.
100
+ If you have the [uglifier](https://github.com/lautis/uglifier) and/or [yui-compressor](https://github.com/sstephenson/ruby-yui-compressor) gems in your Gemfile, you will be able to minify the JS and CSS in a built extension.
89
101
 
90
102
  Usage:
91
103
  tay minify
@@ -130,6 +142,5 @@ The filename of the key can be specified using by setting `key_path` in the Tayf
130
142
 
131
143
  ## TODO
132
144
 
133
- * Generators that can also make haml/coffeescript
134
145
  * Localization of extensions
135
146
  * Generator for extension option pages
data/Rakefile CHANGED
@@ -1,6 +1,28 @@
1
1
  #!/usr/bin/env rake
2
2
  require "bundler/gem_tasks"
3
3
 
4
+ task :build_generators do
5
+ require 'tilt'
6
+ require 'haml'
7
+ require 'coffee-script'
8
+
9
+ templates_dir = Pathname.new('lib//tay/cli/generators/templates').expand_path(File.dirname(__FILE__))
10
+ Dir[templates_dir.join('**/*.coffee')].each do |cs_path|
11
+ File.open(cs_path.sub(/\.coffee/, ''), 'w') do |f|
12
+ f.write Tilt.new(cs_path).render
13
+ end
14
+ end
15
+
16
+ Dir[templates_dir.join('**/*.haml')].each do |haml_path|
17
+ File.open(haml_path.sub(/\.haml/, ''), 'w') do |f|
18
+ html = Tilt.new(haml_path).render
19
+ # We need to fix the ERB tags which have been encoded
20
+ html = html.gsub(/%&gt;/, '%>').gsub(/&lt;%/, '<%')
21
+ f.write html
22
+ end
23
+ end
24
+ end
25
+
4
26
  task :doc do
5
27
  `sdoc`
6
28
  end
@@ -16,6 +16,7 @@ module Tay
16
16
  require 'tay/cli/generators/page_action'
17
17
  require 'tay/cli/generators/browser_action'
18
18
  require 'tay/cli/generators/content_script'
19
+ require 'tay/cli/generators/options_page'
19
20
 
20
21
  protected
21
22
 
@@ -33,12 +34,55 @@ module Tay
33
34
  # Render a template in the context of self and return its contents
34
35
  # Thor does not provide a way to do this.
35
36
  def render_template(path, locals = {})
37
+ path = path.to_s
38
+
39
+ # Try to use a haml file path if available
40
+ if path[/\.html$/] && using_haml?
41
+ begin
42
+ if find_in_source_paths(path + '.haml')
43
+ path = path + '.haml'
44
+ end
45
+ rescue Exception
46
+ end
47
+ end
48
+
36
49
  tayfile_template = Tilt::ERBTemplate.new(find_in_source_paths(path), {
37
50
  :trim => '-'
38
51
  })
39
52
  tayfile_template.render(self, locals)
40
53
  end
41
54
 
55
+ ##
56
+ # Automatically use the coffeescript/haml templates when copying a file
57
+ # if the user has the gems in their gemfile
58
+ def copy_file(from, to)
59
+ from = from.to_s
60
+ to = to.to_s
61
+
62
+ if from[/\.js$/] && using_coffeescript?
63
+ from = from + '.coffee'
64
+ to = to + '.coffee'
65
+ end
66
+
67
+ if from[/\.html$/] && using_haml?
68
+ from = from + '.haml'
69
+ to = to + '.haml'
70
+ end
71
+
72
+ super(from, to)
73
+ end
74
+
75
+ ##
76
+ # Create a file, tacking on .haml if we're using it
77
+ def create_file(path, content, *args)
78
+ path = path.to_s
79
+ if path[/\.html$/] && using_haml?
80
+ path = path + '.haml'
81
+ end
82
+
83
+ super
84
+ end
85
+
42
86
  ##
43
87
  # Get path to src/assets
44
88
  def asset_dir
@@ -12,7 +12,9 @@ module Tay
12
12
  fs_name = Utils.filesystem_name(options['action-name'])
13
13
  copy_file('browser_action/action.js', javascript_dir.join(fs_name+ '.js'))
14
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))
15
+
16
+ create_file(html_dir.join(fs_name + '.html'), render_template('browser_action/action.html', :fs_name => fs_name))
17
+
16
18
  inject_tayfile_content(render_template('browser_action/tayfile', :fs_name => fs_name))
17
19
  end
18
20
  end
@@ -1,16 +1,3 @@
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
1
  module Tay
15
2
  module CLI
16
3
  class Generate < ::Thor
@@ -0,0 +1,17 @@
1
+ module Tay
2
+ module CLI
3
+ class Generate < ::Thor
4
+ desc "options_page", "Generate an options page"
5
+ def options_page
6
+ copy_file('options_page/options.js', javascript_dir.join('options.js'))
7
+ copy_file('options_page/options_page.js', javascript_dir.join('options_page.js'))
8
+ copy_file('options_page/options_server.js', javascript_dir.join('options_server.js'))
9
+ copy_file('options_page/options_page.css', stylesheet_dir.join('options_page.css'))
10
+
11
+ create_file(html_dir.join('options_page.html'), render_template('options_page/options_page.html'))
12
+
13
+ inject_tayfile_content(render_template('options_page/tayfile'))
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,8 @@
1
+ !!!5
2
+ %html
3
+ %head
4
+ %title <%= options['action-name'] %>
5
+ %script{src: "/javascripts/<%= fs_name %>.js"}
6
+ %style{href: "/stylesheets/<%= fs_name %>.css", type: "text/css", rel: "stylesheet"}
7
+ %body
8
+ %h1 Hello World!
@@ -0,0 +1,6 @@
1
+ document.addEventListener 'DOMContentLoaded', ->
2
+ el = document.createElement('p');
3
+ currentTime = (new Date()).toTimeString()
4
+ el.appendChild document.createTextNode("The time is now: #{currentTime}")
5
+ document.body.appendChild el
6
+ , false
@@ -0,0 +1,2 @@
1
+ h1 = document.querySelector 'h1'
2
+ h1.innerHTML = 'Set by content_script.js'
@@ -0,0 +1,33 @@
1
+ class OptionStore
2
+ get: (key, callback) ->
3
+ callback = key if typeof(key) == 'function'
4
+
5
+ if !key or key == callback
6
+ chrome.extension.sendRequest {method: "options.getAll"}, (@options) =>
7
+ @optionsLoaded = true
8
+ callback(options) if callback
9
+ else if @optionsLoaded
10
+ callback @options[key]
11
+ else
12
+ @get =>
13
+ callback(@options[key])
14
+
15
+ setAll: (options) ->
16
+ chrome.extension.sendRequest {
17
+ method: "options.setAll",
18
+ options: options
19
+ }
20
+
21
+ set: (key, value) ->
22
+ if typeof(key) == 'object'
23
+ attrs = key
24
+ else
25
+ attrs = {}
26
+ attrs[key] = value
27
+
28
+ chrome.extension.sendRequest {
29
+ method: "options.setMany",
30
+ options: attrs
31
+ }
32
+
33
+ this.optionStore = new OptionStore
@@ -0,0 +1,55 @@
1
+ body {
2
+ background: #f9f9f9;
3
+ padding: 20px;
4
+ font-size: 75%;
5
+ color: #222;
6
+ font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
7
+ }
8
+
9
+ ul {
10
+ list-style: none;
11
+ margin: 0;
12
+ padding: 0;
13
+ }
14
+
15
+ a {
16
+ color: #0054A6;
17
+ }
18
+ a:hover {
19
+ color: #590;
20
+ cursor: pointer;
21
+ }
22
+
23
+ .module {
24
+ padding: 0;
25
+ border: 1px solid #ccc;
26
+ border-radius: 5px;
27
+ background: white;
28
+ box-shadow: 0px 0px 3px rgba(0,0,0,0.1);
29
+ margin: 0 auto;
30
+ width: 300px;
31
+ }
32
+ .module>.content {
33
+ padding: 10px;
34
+ }
35
+ .module .bottom{
36
+ background-color: #eee;
37
+ border-top: 1px solid #d2d2d2;
38
+ padding: 10px 15px;
39
+ font-weight: bold;
40
+ overflow: hidden;
41
+ border-bottom-left-radius: 5px;
42
+ border-bottom-right-radius: 5px;
43
+ box-shadow: inset 0px 0px 0px 1px #fff;
44
+ }
45
+ .module>h1 {
46
+ font-size: 18px;
47
+ font-weight: bold;
48
+ margin: 10px 10px 0 10px;
49
+ padding: 0 0 10px 0;
50
+ }
51
+ .module>h1>img {
52
+ display:inline-block;
53
+ vertical-align:-15px;
54
+ margin-right:7px
55
+ }
@@ -0,0 +1,38 @@
1
+ !!!5
2
+ %html
3
+ %head
4
+ %title Options
5
+ %link{rel: "stylesheet", type: "text/css", href: "/stylesheets/options_page.css"}
6
+ %body
7
+ .module
8
+ %h1
9
+ Options
10
+ .content
11
+ %form#options
12
+ %ul
13
+ %li
14
+ %label
15
+ A boolean option
16
+ %input{type: "checkbox", name: "boolean_option"}
17
+ %li
18
+ %label
19
+ A text option
20
+ %input{type: "text", name: "string_option"}
21
+ %li
22
+ %label
23
+ A select option
24
+ %select{name: "select_option"}
25
+ %option{value: "1"} One
26
+ %option{value: "2"} Two
27
+ %option{value: "3"} Three
28
+ %li
29
+ %label
30
+ Radio option
31
+ %input{type: "radio", name: "radio_option", value: "a"} A
32
+ %input{type: "radio", name: "radio_option", value: "b"} B
33
+ %input{type: "radio", name: "radio_option", value: "c"} C
34
+
35
+ .bottom
36
+ %a#saveSettings Save your settings
37
+ %script{src: "/javascripts/options.js"}
38
+ %script{src: "/javascripts/options_page.js"}
@@ -0,0 +1,57 @@
1
+ setValueOnInput = (name, value) ->
2
+ inputs = document.querySelectorAll("form#options *[name='#{name}']")
3
+ input = inputs[0]
4
+
5
+ if input.tagName == 'INPUT'
6
+ if input.type == 'checkbox'
7
+ input.checked = true if value
8
+ else if input.type == 'radio'
9
+ Array.prototype.slice.call(inputs,0).some (radio) ->
10
+ if radio.value == value
11
+ radio.checked = true if value
12
+ true
13
+ else
14
+ input.value = value
15
+ else if input.tagName == 'SELECT'
16
+ for option in input.options
17
+ option.selected = true if option.value == value
18
+ else if input.tagName = 'TEXTAREA'
19
+ input.value = value
20
+
21
+ getOptionValuesFromForm = ->
22
+ inputs = document.querySelectorAll("form#options *[name]")
23
+ values = {}
24
+ for input in inputs
25
+ name = input.name
26
+
27
+ if input.tagName == 'INPUT'
28
+ if input.type == 'checkbox'
29
+ values[name] = (input.value || "checked") if input.checked
30
+ else if input.type == 'radio'
31
+ if Object.keys(values).indexOf input.name > -1
32
+ radios = document.querySelectorAll("form#options input[type='radio'][name='#{name}']")
33
+ for radio in radios
34
+ values[name] = radio.value if radio.checked
35
+ else
36
+ values[name] = input.value
37
+ else if input.tagName == 'SELECT'
38
+ for option in input.options
39
+ values[name] = option.value if option.selected
40
+ else if input.tagName = 'TEXTAREA'
41
+ input.value = value
42
+ values
43
+
44
+ ###
45
+ Load the options from the backend and load them in to the form
46
+ ###
47
+ optionStore.get (options) ->
48
+ Object.keys(options).forEach (name) ->
49
+ setValueOnInput(name, options[name])
50
+
51
+ ###
52
+ Take the values from the form and save them to the data store
53
+ ###
54
+ document.getElementById('saveSettings').addEventListener 'click', (event) ->
55
+ optionStore.setAll getOptionValuesFromForm()
56
+ event.preventDefault()
57
+ , false
@@ -0,0 +1,26 @@
1
+ defaultOptions =
2
+ boolean_option: true
3
+ string_option: "@rx"
4
+ select_option: "2"
5
+ radio_option: "b"
6
+
7
+ extendObject = (dest, srcs...) ->
8
+ for src in srcs
9
+ for name in Object.getOwnPropertyNames(src) when name not in dest
10
+ dest[name] = src[name]
11
+ dest
12
+
13
+ options = extendObject {}, defaultOptions, JSON.parse(localStorage.getItem('options') || "{}")
14
+
15
+ chrome.extension.onRequest.addListener (request, sender, sendResponse) ->
16
+ return unless /^options\./.test(request.method)
17
+
18
+ switch request.method
19
+ when "options.getAll"
20
+ sendResponse options
21
+ when "options.setMany"
22
+ extendObject options, request.options
23
+ localStorage.setItem 'options', JSON.stringify(options)
24
+ when "options.setAll"
25
+ options = request.options
26
+ localStorage.setItem 'options', JSON.stringify(options)
@@ -0,0 +1,5 @@
1
+ ext.javascripts << 'javascripts/options.js'
2
+ ext.javascripts << 'javascripts/options_page.js'
3
+ ext.stylesheets << 'stylesheets/options_page.css'
4
+ ext.options_page = 'html/options_page.html'
5
+ ext.background_scripts << 'javascripts/options_server.js'
@@ -0,0 +1,5 @@
1
+ chrome.tabs.onUpdated.addListener (tabId, changed, info) ->
2
+ chrome.pageAction.show tabId
3
+
4
+ chrome.pageAction.onClicked.addListener (tab) ->
5
+ alert "The page action was clicked on tab: #{tab.title}"
@@ -47,6 +47,18 @@ module Tay
47
47
  def build_dir
48
48
  base_dir.join(options['build-directory'] || 'build')
49
49
  end
50
+
51
+ ##
52
+ # Detect if the user has coffee-script in their Gemfile
53
+ def using_coffeescript?
54
+ Gem.loaded_specs.keys.include?('coffee-script')
55
+ end
56
+
57
+ ##
58
+ # Detect if the user has haml in their Gemfile
59
+ def using_haml?
60
+ Gem.loaded_specs.keys.include?('haml')
61
+ end
50
62
  end
51
63
  end
52
64
  end
data/lib/tay/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Tay
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/tay.gemspec CHANGED
@@ -15,6 +15,7 @@ Gem::Specification.new do |gem|
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Tay::VERSION
17
17
 
18
+ gem.add_dependency 'bundler', '>= 1.1.3'
18
19
  gem.add_dependency 'thor', '>= 0.15.2'
19
20
  gem.add_dependency 'tilt', '>= 1.3.3'
20
21
  gem.add_dependency 'sprockets', '>= 2.4.3'
@@ -23,4 +24,6 @@ Gem::Specification.new do |gem|
23
24
  gem.add_development_dependency 'rspec'
24
25
  gem.add_development_dependency 'sdoc'
25
26
  gem.add_development_dependency 'rake'
27
+ gem.add_development_dependency 'coffee-script'
28
+ gem.add_development_dependency 'haml'
26
29
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tay
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,24 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-25 00:00:00.000000000 Z
12
+ date: 2012-05-30 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.1.3
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: 1.1.3
14
30
  - !ruby/object:Gem::Dependency
15
31
  name: thor
16
32
  requirement: !ruby/object:Gem::Requirement
@@ -123,6 +139,38 @@ dependencies:
123
139
  - - ! '>='
124
140
  - !ruby/object:Gem::Version
125
141
  version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: coffee-script
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ - !ruby/object:Gem::Dependency
159
+ name: haml
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
126
174
  description: Tay helps you develop Chrome extensions
127
175
  email:
128
176
  - tom@rixth.org
@@ -144,15 +192,22 @@ files:
144
192
  - lib/tay/cli/generate.rb
145
193
  - lib/tay/cli/generators/browser_action.rb
146
194
  - lib/tay/cli/generators/content_script.rb
195
+ - lib/tay/cli/generators/options_page.rb
147
196
  - lib/tay/cli/generators/page_action.rb
148
197
  - 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
198
+ - lib/tay/cli/generators/templates/browser_action/action.html.haml
199
+ - lib/tay/cli/generators/templates/browser_action/action.js.coffee
151
200
  - lib/tay/cli/generators/templates/browser_action/tayfile
152
201
  - lib/tay/cli/generators/templates/content_script/content_script.css
153
- - lib/tay/cli/generators/templates/content_script/content_script.js
202
+ - lib/tay/cli/generators/templates/content_script/content_script.js.coffee
154
203
  - lib/tay/cli/generators/templates/content_script/tayfile
155
- - lib/tay/cli/generators/templates/page_action/controller.js
204
+ - lib/tay/cli/generators/templates/options_page/options.js.coffee
205
+ - lib/tay/cli/generators/templates/options_page/options_page.css
206
+ - lib/tay/cli/generators/templates/options_page/options_page.html.haml
207
+ - lib/tay/cli/generators/templates/options_page/options_page.js.coffee
208
+ - lib/tay/cli/generators/templates/options_page/options_server.js.coffee
209
+ - lib/tay/cli/generators/templates/options_page/tayfile
210
+ - lib/tay/cli/generators/templates/page_action/controller.js.coffee
156
211
  - lib/tay/cli/generators/templates/page_action/icon.png
157
212
  - lib/tay/cli/generators/templates/page_action/tayfile
158
213
  - lib/tay/cli/helpers.rb
@@ -194,7 +249,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
194
249
  version: '0'
195
250
  segments:
196
251
  - 0
197
- hash: -3059562880123652420
252
+ hash: 1815708585182084014
198
253
  required_rubygems_version: !ruby/object:Gem::Requirement
199
254
  none: false
200
255
  requirements:
@@ -203,7 +258,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
203
258
  version: '0'
204
259
  segments:
205
260
  - 0
206
- hash: -3059562880123652420
261
+ hash: 1815708585182084014
207
262
  requirements: []
208
263
  rubyforge_project:
209
264
  rubygems_version: 1.8.24
@@ -1,11 +0,0 @@
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>
@@ -1,5 +0,0 @@
1
- document.addEventListener('DOMContentLoaded', function () {
2
- var el = document.createElement('p');
3
- el.appendChild(document.createTextNode('The time is now: ' + (new Date()).toTimeString()));
4
- document.body.appendChild(el);
5
- }, false);
@@ -1,4 +0,0 @@
1
- (function () {
2
- var h1 = document.querySelector('h1');
3
- h1.innerHTML = 'Set by content_script.js';
4
- }());
@@ -1,7 +0,0 @@
1
- chrome.tabs.onUpdated.addListener(function (tabId, changed, info) {
2
- chrome.pageAction.show(tabId);
3
- });
4
-
5
- chrome.pageAction.onClicked.addListener(function (tab) {
6
- alert('The page action was clicked on tab: ' + tab.title)
7
- });