tap-ubiquity 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/History CHANGED
@@ -1,3 +1,7 @@
1
+ == 0.4.0 / 2009-06-17
2
+
3
+ Updates to utilize Tap-0.18.0. Cleanup and documentation.
4
+
1
5
  == 0.3.0 / 2009-05-25
2
6
 
3
7
  Updates to utilize Tap-0.17.0
data/README CHANGED
@@ -1,7 +1,30 @@
1
- = Tap-Ubiqity
1
+ = Tap-Ubiquity
2
2
 
3
3
  A gem making {Tap}[http://tap.rubyforge.org] available in
4
- {Ubiqity}[http://labs.mozilla.com/2008/08/introducing-ubiquity/]
4
+ {Ubiquity}[http://labs.mozilla.com/2008/08/introducing-ubiquity/]
5
+
6
+ == Description
7
+
8
+ Tap-Ubiquity allows you to dynamically reprocess web content into new web
9
+ pages and to manipulate web content within existing pages.
10
+
11
+ * Website[http://tap.rubyforge.org/tap-ubiquity]
12
+ * GitHub[http://github.com/bahuvrihi/tap-ubiquity/tree/master] Issues[http://github.com/bahuvrihi/tap-ubiquity/issues]
13
+ * {Google Group}[http://groups.google.com/group/ruby-on-tap]
14
+
15
+ == Usage
16
+
17
+ To get a feel for what is possible with Tap-Ubiquity:
18
+
19
+ * Install {Ubiquity}[http://labs.mozilla.com/2008/08/introducing-ubiquity/]
20
+ * Install Tap-Ubiquity (see below)
21
+
22
+ And then start a tap server:
23
+
24
+ % tap server
25
+
26
+ Now in Firefox, go to the Tutorial (http://localhost:8080/ubiquity) and
27
+ follow the example.
5
28
 
6
29
  == Installation
7
30
 
@@ -1,24 +1,73 @@
1
1
  require 'tap/controller'
2
- require 'json'
2
+ require 'tap/ubiquity/utils'
3
3
 
4
4
  module Tap
5
5
  module Ubiquity
6
6
 
7
- # ::controller
7
+ # :startdoc::controller an index of available ubiquity feeds
8
+ # :startdoc::ubiquity
9
+ # :startdoc:::-
10
+ #
11
+ # The Ubiquity controller provides an index of feeds available in the
12
+ # current environment. Ubiquity expects to run with a Tap::Server
13
+ # that has a router (otherwise the uris for the feeds may be off).
14
+ #
15
+ # % tap server
16
+ #
17
+ # Ubiquity controllers are identifies by the '::ubiquity' resource
18
+ # identifier. The subject of the identifier specifies which action
19
+ # provides the feed. The default action is 'commands'; multiple
20
+ # commands can be provided from the same feed.
21
+ #
22
+ # Note that ubiquity controllers must also be identified as controllers
23
+ # using the '::controller' resource id.
24
+ #
25
+ # See Tap::Ubiquity::Utils for more information.
26
+ #
27
+ # :startdoc:::+
8
28
  class Ubiquity < Tap::Controller
9
29
  UBIQUITY_WEBSITE = "http://labs.mozilla.com/projects/ubiquity/"
10
-
30
+
31
+ include Utils
32
+
33
+ # Renders an index of the available feeds.
11
34
  def index
12
35
  link = {:uri => request['uri'], :name => request['name']}
13
36
  render 'index.erb', :locals => {:feeds => feeds, :link => link}
14
37
  end
15
-
38
+
39
+ # Serves the echo and alert actions as examples of standard and
40
+ # javascript injection commands.
41
+ def commands
42
+ serve command(:echo) + js_injection(:alert)
43
+ end
44
+
45
+ # An example of a command action.
46
+ def echo
47
+ input = request['input']
48
+ if request.get?
49
+ "Got: #{input}"
50
+ else
51
+ render 'echo.erb', :locals => {:input => input}
52
+ end
53
+ end
54
+
55
+ # An example of a js_injection action.
56
+ def alert
57
+ response['Content-Type'] = 'text/plain'
58
+ "alert('#{request['input']}')"
59
+ end
60
+
16
61
  protected
17
62
 
63
+ # helper to provide the ubiquity website
18
64
  def ubiquity_website
19
65
  UBIQUITY_WEBSITE
20
66
  end
21
67
 
68
+ # Returns an array of (uri, key) arrays identifying command feeds.
69
+ # The uris are relative to the domain and so require a server with
70
+ # a router.
22
71
  def feeds
23
72
  env_names = {}
24
73
  server.env.minimap.each do |env_name, env|
@@ -29,10 +78,12 @@ module Tap
29
78
  server.env.each do |env|
30
79
  env_name = env_names[env]
31
80
 
32
- env.constant_manifest(:ubiquity).minimap.each do |name, constant|
81
+ env.manifest(:ubiquity).minimap.each do |name, constant|
33
82
  action = constant.comment.strip
34
83
  action = 'commands' if action.empty?
35
- feeds << [server.uri(name, action), "#{env_name}:#{name}"]
84
+ key = "#{env_name}:#{name}"
85
+
86
+ feeds << ["/#{escape(key)}/#{action}", key]
36
87
  end
37
88
  end
38
89
 
@@ -1,10 +1,11 @@
1
1
  require 'json'
2
+ require 'tap/controller/extname'
2
3
 
3
4
  module Tap
4
5
  module Ubiquity
5
6
 
6
7
  # Utils provides methods for serving ubiquity commands that link back to
7
- # actions on a controller.
8
+ # actions on a controller.
8
9
  #
9
10
  # :startdoc:::-
10
11
  # # ::controller
@@ -25,120 +26,86 @@ module Tap
25
26
  #
26
27
  # Utils expects to be included in a Tap::Controller.
27
28
  module Utils
29
+ include Tap::Controller::Extname
28
30
 
29
31
  # Serves the command from the calling method.
30
32
  def serve(command)
31
- response['Content-Type'] = 'application/x-javascript'
32
- command
33
+ if extname == '.js'
34
+ response['Content-Type'] = 'application/x-javascript'
35
+ command
36
+ else
37
+ caller[0] =~ /in\W+(\w+)\W$/
38
+ "<pre>#{command}</pre>#{command_link(uri($1))}"
39
+ end
33
40
  end
34
41
 
35
42
  # Returns the link tag for subscribing to a ubiquity command served
36
43
  # from the specified action.
37
44
  def command_link(href)
38
- "<link rel='commands' href='#{href}' />"
45
+ "<link rel='commands' href='#{href}.js' />"
39
46
  end
40
47
 
41
- # Formats a Ubiquity command that calls action with an 'input' parameter
42
- # containing the currently selected text. If the request is a get, the
43
- # action results will be set in the preview box. Otherwise the current
44
- # page is redirected to the action url.
48
+ # Returns a ubiquity command to redirect to action. The action may
49
+ # respond differentl to GET and POST requests; GET results will be
50
+ # displayed in the preview box and the browser will be redirected
51
+ # to view POST results.
52
+ #
53
+ # The action will be called with an 'input' parameter that provides
54
+ # the currently selected text in the browser.
55
+ #
56
+ # ==== Example
57
+ #
58
+ # class Sample < Tap::Controller
59
+ # include Ubiquity::Utils
60
+ #
61
+ # def commands
62
+ # serve command(:echo)
63
+ # end
64
+ #
65
+ # def echo
66
+ # input = request['input']
67
+ # request.get? ? "got: #{input}" : "received: #{input}"
68
+ # end
69
+ # end
45
70
  #
46
71
  #-- TODO
47
72
  # name should be minipath, not action
48
- def command(action, attrs={})
49
- attrs = {:name => action}.merge(attrs)
50
- %Q{
51
- var cmd = #{attrs.to_json};
52
- cmd.takes = {"selection": noun_arb_text};
53
- cmd.preview = function( pblock, selection ) {
54
- jQuery.ajax({
55
- type: 'GET',
56
- url: '#{uri(action)}',
57
- data: {input: selection.text},
58
- success: function(data) {
59
- pblock.innerHTML = data;
60
- },
61
- error: function(XMLHttpRequest, textStatus, errorThrown) {
62
- pblock.innerHTML = "Could not generate preview: " + errorThrown;
63
- },
64
- });
65
- };
66
- cmd.execute = function(selection) {
67
- var document = Application.activeWindow.activeTab.document;
68
-
69
- var form = document.createElement("form");
70
- form.setAttribute('action', '#{uri(action)}');
71
- form.setAttribute('style', 'display:none');
72
- form.setAttribute('method', 'POST');
73
-
74
- var input = document.createElement('input');
75
- input.setAttribute('name', 'input');
76
- input.setAttribute('type', 'text');
77
- input.value = selection.text;
78
- form.appendChild(input);
79
-
80
- document.body.appendChild(form);
81
- form.submit();
82
- };
83
-
84
- CmdUtils.CreateCommand(cmd);
85
- }
73
+ def command(action, cmd={})
74
+ render 'command.js', :locals => {
75
+ :cmd => {:name => action}.merge(cmd),
76
+ :uri => uri(:action => action)
77
+ }
86
78
  end
87
79
 
80
+ # Returns a ubiquity command to inject javascript into the current
81
+ # page. The javascript is returned by action and should have a
82
+ # 'text/plain' content type. The action may respond differently to
83
+ # GET and POST requests; GET results will be displayed in the preview
84
+ # box while POST results will actually be injected.
85
+ #
86
+ # The action will be called with an 'input' parameter that provides
87
+ # the currently selected text in the browser.
88
+ #
89
+ # ==== Example
90
+ #
88
91
  # class Sample < Tap::Controller
89
92
  # include Ubiquity::Utils
90
93
  #
91
94
  # def commands
92
- # serve js_injection(:action)
95
+ # serve js_injection(:alert)
93
96
  # end
94
97
  #
95
- # def action
98
+ # def alert
96
99
  # response['Content-Type'] = 'text/plain'
97
100
  # "alert('#{request['input']}')"
98
101
  # end
99
102
  # end
100
103
  #
101
- def js_injection(action, attrs={}, inject=true)
102
- attrs = {:name => action}.merge(attrs)
103
- %Q{
104
- var cmd = #{attrs.to_json};
105
- cmd.takes = {"selection": noun_arb_text};
106
- cmd.preview = function( pblock, selection ) {
107
- jQuery.ajax({
108
- type: 'GET',
109
- url: '#{uri(action)}',
110
- data: {input: selection.text},
111
- success: function(data) {
112
- pblock.innerHTML = data;
113
- },
114
- error: function(XMLHttpRequest, textStatus, errorThrown) {
115
- pblock.innerHTML = "Could not generate preview: " + errorThrown;
116
- },
117
- });
118
- };
119
- cmd.execute = function(selection) {
120
- jQuery.ajax({
121
- type: 'POST',
122
- url: '#{uri(action)}',
123
- data: {input: selection.text},
124
- success: function(data) {
125
- if(#{inject ? 'true' : 'false'}) {
126
- var doc = Application.activeWindow.activeTab.document;
127
- var script = doc.createElement("script");
128
- script.type = "text/javascript";
129
- script.innerHTML = data;
130
- doc.body.appendChild(script);
131
- } else {
132
- eval(data);
133
- }
134
- },
135
- error: function(XMLHttpRequest, textStatus, errorThrown) {
136
- displayMessage("Could not execute: " + errorThrown);
137
- },
138
- });
139
- };
140
-
141
- CmdUtils.CreateCommand(cmd);}
104
+ def js_injection(action, cmd={})
105
+ render 'js_injection.js', :locals => {
106
+ :cmd => {:name => action}.merge(cmd),
107
+ :uri => uri(:action => action)
108
+ }
142
109
  end
143
110
  end
144
111
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "tap-ubiquity"
3
- s.version = "0.3.0"
3
+ s.version = "0.4.0"
4
4
  s.author = "Simon Chiang"
5
5
  s.email = "simon.a.chiang@gmail.com"
6
6
  s.homepage = "http://tap.rubyforge.org/ubiquity/"
@@ -27,7 +27,9 @@ Gem::Specification.new do |s|
27
27
  lib/tap/ubiquity/utils.rb
28
28
  tap-ubiquity.gemspec
29
29
  tap.yml
30
- views/tap/ubiquity/ubiquity/commands.js
30
+ views/tap/ubiquity/ubiquity/echo.erb
31
31
  views/tap/ubiquity/ubiquity/index.erb
32
+ views/tap/ubiquity/utils/command.js
33
+ views/tap/ubiquity/utils/js_injection.js
32
34
  }
33
35
  end
@@ -0,0 +1,5 @@
1
+ <h1>Recieved:</h1>
2
+ <blockquote>
3
+ <%= input %>
4
+ </blockquote>
5
+ <p>Back to <a href="<%= uri %>">Tutorial</a></p>
@@ -1,15 +1,24 @@
1
- <h1>Welcome to Tap!</h1>
1
+ <h1>Welcome!</h1>
2
2
 
3
- <p><a href="http://tap.rubyforge.org">Tap</a> interfaces with the web using <a href="<%= ubiquity_website %>">Ubiquity</a>.</p>
3
+ <p><a href="http://tap.rubyforge.org">Tap</a> interfaces with the web using <a
4
+ href="<%= ubiquity_website %>">Ubiquity</a>.</p>
5
+
6
+ <h2>Tutorial</h2>
7
+ <p>To get a sense for what is possible using this gem:</p>
4
8
  <ul>
9
+ <li>Subscribe to the 'tap-ubiquity:ubiquity' feed</li>
10
+ <li>Select some text on this page</li>
5
11
  <li>Press 'option' + 'space' to bring up a prompt</li>
12
+ <li>Type in 'echo' or 'alert' and hit enter</li>
6
13
  </ul>
7
14
 
8
- <% unless feeds.empty? %>
9
- <p>Subscribe to local feeds by clicking on the links below:</p>
15
+ <p>You should see the selected text echoed back to you, either as a new web
16
+ page or in an alert box. Your selection was sent to the server, processed by
17
+ a controller written in ruby, and the result was displayed by the browser.</p>
18
+
19
+ <h2>Feeds:</h2>
10
20
  <ul>
11
21
  <% feeds.each do |(uri, name)| %>
12
22
  <li><a href="<%= uri %>"><%= name %></a></li>
13
23
  <% end %>
14
- </ul>
15
- <% end %>
24
+ </ul>
@@ -0,0 +1,34 @@
1
+ var cmd = <%= cmd.to_json %>;
2
+ cmd.takes = {"selection": noun_arb_text};
3
+ cmd.preview = function( pblock, selection ) {
4
+ jQuery.ajax({
5
+ type: 'GET',
6
+ url: '<%= uri %>',
7
+ data: {input: selection.text},
8
+ success: function(data) {
9
+ pblock.innerHTML = data;
10
+ },
11
+ error: function(XMLHttpRequest, textStatus, errorThrown) {
12
+ pblock.innerHTML = "Could not generate preview: " + errorThrown;
13
+ },
14
+ });
15
+ };
16
+ cmd.execute = function(selection) {
17
+ var document = Application.activeWindow.activeTab.document;
18
+
19
+ var form = document.createElement("form");
20
+ form.setAttribute('action', '<%= uri %>');
21
+ form.setAttribute('style', 'display:none');
22
+ form.setAttribute('method', 'POST');
23
+
24
+ var input = document.createElement('input');
25
+ input.setAttribute('name', 'input');
26
+ input.setAttribute('type', 'text');
27
+ input.value = selection.text;
28
+ form.appendChild(input);
29
+
30
+ document.body.appendChild(form);
31
+ form.submit();
32
+ };
33
+
34
+ CmdUtils.CreateCommand(cmd);
@@ -0,0 +1,34 @@
1
+ var cmd = <%= cmd.to_json %>;
2
+ cmd.takes = {"selection": noun_arb_text};
3
+ cmd.preview = function( pblock, selection ) {
4
+ jQuery.ajax({
5
+ type: 'GET',
6
+ url: '<%= uri %>',
7
+ data: {input: selection.text},
8
+ success: function(data) {
9
+ pblock.innerHTML = data;
10
+ },
11
+ error: function(XMLHttpRequest, textStatus, errorThrown) {
12
+ pblock.innerHTML = "Could not generate preview: " + errorThrown;
13
+ },
14
+ });
15
+ };
16
+ cmd.execute = function(selection) {
17
+ jQuery.ajax({
18
+ type: 'POST',
19
+ url: '<%= uri %>',
20
+ data: {input: selection.text},
21
+ success: function(data) {
22
+ var doc = Application.activeWindow.activeTab.document;
23
+ var script = doc.createElement("script");
24
+ script.type = "text/javascript";
25
+ script.innerHTML = data;
26
+ doc.body.appendChild(script);
27
+ },
28
+ error: function(XMLHttpRequest, textStatus, errorThrown) {
29
+ displayMessage("Could not execute: " + errorThrown);
30
+ },
31
+ });
32
+ };
33
+
34
+ CmdUtils.CreateCommand(cmd);
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tap-ubiquity
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Chiang
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-05-25 00:00:00 -06:00
12
+ date: 2009-06-17 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -47,8 +47,10 @@ files:
47
47
  - lib/tap/ubiquity/utils.rb
48
48
  - tap-ubiquity.gemspec
49
49
  - tap.yml
50
- - views/tap/ubiquity/ubiquity/commands.js
50
+ - views/tap/ubiquity/ubiquity/echo.erb
51
51
  - views/tap/ubiquity/ubiquity/index.erb
52
+ - views/tap/ubiquity/utils/command.js
53
+ - views/tap/ubiquity/utils/js_injection.js
52
54
  - MIT-LICENSE
53
55
  - README
54
56
  - History
@@ -1,88 +0,0 @@
1
- var Dispatch = {
2
-
3
- /* Sends a preview request from the server and sets the preview
4
- * block innerHTML on success. */
5
- preview: function(pblock, data) {
6
- jQuery.ajax({
7
- type: "GET",
8
- url: "<%= uri(:dispatch) %>",
9
- data: data,
10
- dataType: 'html',
11
- success: function(html, textStatus) {
12
- pblock.innerHTML = html;
13
- },
14
- error: function(XMLHttpRequest, textStatus, errorThrown) {
15
- Dispatch.ping("Error generating preview: " + textStatus);
16
- },
17
- });
18
- },
19
-
20
- /* Sends an execute request to the server. A successful response is a
21
- * JSON object specifying 'inject' (true or false) and 'script'. The
22
- * script is injected into the DOM as a <script> tag if inject is true,
23
- * or evaluated in the context of Ubiquity if inject is false.
24
- */
25
- execute: function(data) {
26
- jQuery.ajax({
27
- type: "POST",
28
- url: "<%= uri(:dispatch) %>",
29
- data: data,
30
- dataType: 'json',
31
- success: function(json, textStatus) {
32
- if(json.inject) {
33
- var doc = Application.activeWindow.activeTab.document;
34
- var script = doc.createElement("script");
35
- script.type = "text/javascript";
36
- script.innerHTML = json.script;
37
- doc.body.appendChild(script);
38
- } else {
39
- eval(json.script);
40
- }
41
- },
42
- error: function(XMLHttpRequest, textStatus, errorThrown) {
43
- Dispatch.ping("Error executing command: " + textStatus);
44
- },
45
- });
46
- },
47
-
48
- /* Pings the server to check if it is active. */
49
- ping: function(active_msg) {
50
- jQuery.ajax({
51
- type: "GET",
52
- url: "<%= uri(:ping) %>",
53
- success: function(response, textStatus) {
54
- displayMessage(active_msg);
55
- },
56
- error: function(XMLHttpRequest, textStatus, errorThrown) {
57
- displayMessage("No server is active at: <%= uri %>");
58
- },
59
- });
60
- },
61
- };
62
-
63
- /////////////////////////////////////////////////////////////////////////////
64
- //
65
- // Generated Commands
66
- //
67
- /////////////////////////////////////////////////////////////////////////////
68
-
69
- <% commands.each do |cmd| %>
70
- CmdUtils.CreateCommand({
71
- name: "<%= cmd[:name] %>",
72
- description: "<%= cmd[:description] %>",
73
- help: "<%= cmd[:help] %>",
74
- takes: {"what": noun_arb_text},
75
-
76
- data: function(what) {
77
- return {what: what.text, name: '<%= cmd[:name] %>'};
78
- },
79
-
80
- preview: function(pblock, what) {
81
- Dispatch.preview(pblock, this.data(what));
82
- },
83
-
84
- execute: function(what) {
85
- Dispatch.execute(this.data(what));
86
- },
87
- });
88
- <% end %>