tap-ubiquity 0.3.0 → 0.4.0

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/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 %>