iated 0.0.1

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.
Files changed (54) hide show
  1. data/.gitignore +6 -0
  2. data/Gemfile +3 -0
  3. data/Guardfile +24 -0
  4. data/LICENSE +23 -0
  5. data/Makefile +72 -0
  6. data/README.md +87 -0
  7. data/Rakefile +10 -0
  8. data/bin/iated +13 -0
  9. data/config.ru +5 -0
  10. data/extensions/chrome/background.html +5 -0
  11. data/extensions/chrome/background.js +105 -0
  12. data/extensions/chrome/contentscript.css +0 -0
  13. data/extensions/chrome/contentscript.js +110 -0
  14. data/extensions/chrome/jquery-ui.js +45 -0
  15. data/extensions/chrome/jquery.js +16 -0
  16. data/extensions/chrome/jquery.updater.js +46 -0
  17. data/extensions/chrome/manifest.json +19 -0
  18. data/extensions/chrome/yaml.js +489 -0
  19. data/extensions/tests/simple.html +23 -0
  20. data/features/extension_authenticates.feature +30 -0
  21. data/features/extension_edits.feature +45 -0
  22. data/features/step_definitions/extension_steps.rb +134 -0
  23. data/features/support/env.rb +47 -0
  24. data/features/support/hooks.rb +11 -0
  25. data/iated.gemspec +48 -0
  26. data/lib/iated.rb +111 -0
  27. data/lib/iated/browser_token_db.rb +76 -0
  28. data/lib/iated/edit_session.rb +221 -0
  29. data/lib/iated/helpers.rb +9 -0
  30. data/lib/iated/mcp.rb +144 -0
  31. data/lib/iated/page_helpers.rb +33 -0
  32. data/lib/iated/public/jquery-ui.js +101 -0
  33. data/lib/iated/public/jquery.js +2 -0
  34. data/lib/iated/public/robots.txt +5 -0
  35. data/lib/iated/server.rb +162 -0
  36. data/lib/iated/sys_pref.rb +201 -0
  37. data/lib/iated/version.rb +3 -0
  38. data/lib/iated/views/hello.haml +13 -0
  39. data/lib/iated/views/preferences.haml +27 -0
  40. data/lib/iated/views/reference.coffee +79 -0
  41. data/lib/iated/views/reference.haml +94 -0
  42. data/lib/iated/views/reference.scss +36 -0
  43. data/lib/iated/views/root.haml +13 -0
  44. data/spec/lib/iated/browser_token_db_spec.rb +68 -0
  45. data/spec/lib/iated/edit_session_spec.rb +157 -0
  46. data/spec/lib/iated/mcp_spec.rb +86 -0
  47. data/spec/lib/iated/sys_pref_spec.rb +40 -0
  48. data/spec/protocol/edit_spec.rb +88 -0
  49. data/spec/protocol/hello_spec.rb +18 -0
  50. data/spec/protocol/notfound_spec.rb +11 -0
  51. data/spec/protocol/ping_spec.rb +10 -0
  52. data/spec/protocol/preferences_spec.rb +35 -0
  53. data/spec/spec_helper.rb +21 -0
  54. metadata +460 -0
@@ -0,0 +1,6 @@
1
+ *~
2
+ /pkg/
3
+ /.bundle/
4
+ /.yardoc/
5
+ /Gemfile.lock
6
+ /doc/
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
@@ -0,0 +1,24 @@
1
+ # -*- ruby -*-
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ #guard 'spork' do
5
+ # #watch('config/application.rb')
6
+ # #watch('config/environment.rb')
7
+ # #watch(%r{^config/environments/.+\.rb$})
8
+ # #watch(%r{^config/initializers/.+\.rb$})
9
+ # watch('spec/spec_helper.rb')
10
+ #end
11
+
12
+ guard 'rspec', :version => 2 do
13
+ watch(%r{^spec/.+_spec\.rb$})
14
+ watch(%r{^src/lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
15
+ watch('spec/spec_helper.rb') { "spec/" }
16
+ watch('src/lib/iated.rb') { "spec/" }
17
+ end
18
+
19
+ guard 'cucumber' do
20
+ watch(%r{^features/.+\.feature$})
21
+ watch(%r{^features/support/.+$}) { 'features' }
22
+ watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
23
+ #watch(%r{^src/lib/.+$}) { 'features' }
24
+ end
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ The MIT License
2
+ http://www.opensource.org/licenses/mit-license.php
3
+
4
+ Copyright (c) 2011 Christian Höltje (http://docwhat.org/)
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ "Software"), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,72 @@
1
+ ### Makefile --- Build the doctor jar and exe.
2
+
3
+ SOURCE:=$(shell find src -type f)
4
+ BUILD_SOURCE:=$(patsubst src/%, build/%, $(SOURCE))
5
+ TEST_SOURCE := $(shell find spec -type f -iname '*.rb')
6
+
7
+ # Downloadables
8
+ LAUNCH4J_URL := http://sourceforge.net/projects/launch4j/files/launch4j-3/3.0.2/launch4j-3.0.2-macosx.tgz
9
+
10
+ # Commands
11
+ JRUBY:=jruby $(OPT)
12
+ WARBLE:=$(JRUBY) -S warble
13
+
14
+ .PHONY: all
15
+ all: build
16
+
17
+ ## Execute the tool
18
+ .PHONY: exec
19
+ exec:
20
+ cd src && env RUBYLIB=./lib $(JRUBY) bin/iated --debug
21
+
22
+ ## Execute tests and coverage
23
+ .PHONY: test
24
+ test:
25
+ $(JRUBY) -S rspec spec
26
+
27
+ .PHONY: coverage
28
+ coverage: $(TEST_SOURCE)
29
+ $(JRUBY) -S jrcov --output target/coverage -I src/lib $(TEST_SOURCE)
30
+
31
+ ## Setup the environment
32
+ .PHONY: setup
33
+ setup: cache/launch4j/launch4j
34
+ $(JRUBY) -S jbundle
35
+
36
+ cache/launch4j/launch4j:
37
+ mkdir -p cache
38
+ cd cache && wget -N $(LAUNCH4J_URL)
39
+ cd cache && tar xf $(notdir $(LAUNCH4J_URL))
40
+
41
+ ## Build the tool
42
+ .PHONY: build
43
+ build: target/iated.jar target/iated.exe
44
+
45
+ .PHONY: jar
46
+ jar: target/iated.jar
47
+
48
+ .PHONY: exe
49
+ exe: target/iated.exe
50
+
51
+ target/iated.exe: target/iated.jar
52
+ @if [ ! -x cache/launch4j/launch4j ]; then echo "Run 'make setup'"; exit 10; fi
53
+ cd target && env -u OPT ../cache/launch4j/launch4j $$(pwd)/../launch4j-config.xml
54
+
55
+ target/iated.jar: build/build.jar
56
+ mkdir -p target
57
+ cp -f $< $@
58
+
59
+ $(BUILD_SOURCE):build/%: src/%
60
+ mkdir -p $(dir $@)
61
+ cp -f $< $@
62
+
63
+ build/build.jar: $(BUILD_SOURCE)
64
+ cd build && $(WARBLE) jar:clean jar
65
+
66
+
67
+ ## Clean
68
+ .PHONY: clean
69
+ clean:
70
+ rm -rf target build
71
+
72
+ ### Makefile ends here
@@ -0,0 +1,87 @@
1
+ # It's All Text! Editor Daemon
2
+
3
+ This gem is the core of the *It's All Text! Editor Daemon*.
4
+
5
+ The *IAT Editor Daemon* is a restful web server that allows you to
6
+ open text data in the editor of your choice.
7
+
8
+ ## Bugs and Issues
9
+
10
+ See [the github Issue tracker](https://github.com/docwhat/iated/issues)
11
+
12
+ ## Developer Quickstart
13
+
14
+ 1. `bundle install`
15
+ 2. `rake spec`
16
+
17
+ ### Requirements
18
+
19
+ * Ruby (preferrably 1.9.2+, but 1.8.7 should work)
20
+
21
+ ## API
22
+
23
+ The API is documented in the `features/extension_*.feature` files. You
24
+ can run cucumber to read them.
25
+
26
+ ### Open preferences
27
+
28
+ `GET /preferences` requires "token".
29
+
30
+ Opens a web-page displaying the preferences. Note, there are other
31
+ URLs that Iated supports for modifying the preferences.
32
+
33
+ `GET /preferences/set-editor` require "token".
34
+
35
+ This opens a dialog on the system running Iated to choose the editor.
36
+
37
+ ## Example sessions.
38
+
39
+ The letter `b:` is the browser's requests. `s:` is the server's
40
+ response. Side-effects are in square braces (`[]`).
41
+
42
+ ### Initial authentication
43
+
44
+ b: GET /hello
45
+ s: ok [a popup with the secret is shown]
46
+ b: POST /hello with data: secret=NNNN
47
+ s: token=<MMMMMMMMMMMMMMMMM>
48
+
49
+ ### Editing session
50
+
51
+ b: POST /edit text=<textarea data> url=<someurl> id=<textarea-id>
52
+ s: <sid>
53
+ b: GET /edit/<sid>
54
+ s: nochange
55
+ b: GET /edit/<sid>
56
+ s: <next textarea data>
57
+
58
+ ## Iated Dialogs
59
+
60
+ This is a list of dialogs that Iated needs to be able to generate:
61
+
62
+ * Set Editor -- The dialog to select an editor.
63
+ * Auth Code -- A dialog to show the auth-code for entering in the
64
+ browser.
65
+ * Select Port -- A dialog to select the port to run on for the first
66
+ time or if changing.
67
+
68
+
69
+ ## Future notes
70
+
71
+ At some point I'm going to need concurrancy. I'm thinking
72
+ [jetlang](http://code.google.com/p/jetlang/) (a java library) is the
73
+ right way to go. It's Erlang style concurrancy, so it'll scale well
74
+ and should be safe without having to worry about joins, etc. There is
75
+ a ruby gem called [jretlang](http://github.com/reevesg/jretlang)
76
+
77
+ Some info here:
78
+
79
+ * [Concurrancy models in JRuby using jetlang](http://www.blog.wordaligned.com/2010/02/17/concurrency-models-in-jruby-using-jetlang/)
80
+ * [What is erlang style concurrency?](http://ulf.wiger.net/weblog/2008/02/06/what-is-erlang-style-concurrency/)
81
+ * [LWN article](http://lwn.net/Articles/441790/)
82
+
83
+ ## License
84
+
85
+ Iated is licensed under the
86
+ [MIT License](http://www.opensource.org/licenses/mit-license.php). A
87
+ `LICENSE` file should have been included with this code.
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require "rspec/core/rake_task"
4
+ require "yard"
5
+ require "yard/rake/yardoc_task"
6
+
7
+ RSpec::Core::RakeTask.new
8
+ YARD::Rake::YardocTask.new do |t|
9
+ t.files = ['lib/**/*.rb']
10
+ end
@@ -0,0 +1,13 @@
1
+ #!ruby
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ Bundler.setup(:default)
6
+ require 'pathname'
7
+ $: << (Pathname.new(__FILE__).dirname.dirname + 'lib').to_s
8
+
9
+ require 'iated'
10
+
11
+ Iated::Application.new.run
12
+
13
+ # EOF
@@ -0,0 +1,5 @@
1
+
2
+ $: << ::File.expand_path('../lib', __FILE__)
3
+ require 'iated/server'
4
+
5
+ run Iated::Server
@@ -0,0 +1,5 @@
1
+ <!DOCTYPE html>
2
+ <meta charset=utf-8>
3
+ <script src="jquery.js"></script>
4
+ <script src="yaml.js"></script>
5
+ <script src="background.js"></script>
@@ -0,0 +1,105 @@
1
+ /** The base URL for requests.
2
+ */
3
+ var base_url = 'http://127.0.0.1:9090/';
4
+ var token = '655a93c645d1bf5d5ee972caf0eeaa86';
5
+
6
+ /** Initialize the background handlers.
7
+ */
8
+ function init() {
9
+ console.debug('IAT background loading...');
10
+
11
+ /* Defaults for ajax requests. */
12
+ $.ajaxSetup({
13
+ cache: false
14
+ });
15
+
16
+ /* Set up the listener. */
17
+ chrome.extension.onRequest.addListener(onRequest);
18
+
19
+ console.debug('IAT background loaded.');
20
+ }
21
+
22
+ /** Handles request from contentscript.js
23
+ * @param msg Object Data sent in the request.
24
+ * @param sender Object Origin of the request.
25
+ * @param callback Function The method to call when the request completes.
26
+ */
27
+ function onRequest(msg, sender, callback) {
28
+ if ('edit' === msg.action) {
29
+ edit(msg.text, msg.url, msg.id, callback);
30
+ } else if ('update' == msg.action) {
31
+ update(msg.sid, msg.change_id, callback);
32
+ } else {
33
+ console.error("Unknown msg: ", msg);
34
+ }
35
+ };
36
+
37
+ /** Handles an edit request.
38
+ * @param text
39
+ * @param url
40
+ * @param id
41
+ */
42
+ function edit(text, url, id, callback) {
43
+ var data = {
44
+ text : text,
45
+ token : token
46
+ };
47
+ if (url) {
48
+ data.url = url;
49
+ }
50
+ if (id) {
51
+ data.id = id;
52
+ }
53
+ data.extension = '.txt';
54
+ $.ajax({
55
+ url: base_url + 'edit',
56
+ type: 'POST',
57
+ data: data,
58
+ dataType: 'text',
59
+ success: function (resp, textStatus) {
60
+ resp = YAML.eval(resp);
61
+ console.log("NARF edit response: %o %o", resp, textStatus);
62
+ callback({sid: resp.sid});
63
+ },
64
+ error: function (jqXHR, textStatus, errorThrown) {
65
+ console.error("edit: failure: %o - %o - %o", jqXHR, textStatus, errorThrown);
66
+ callback({ error: "Unable to get update from Iated" });
67
+ }
68
+ });
69
+ }
70
+
71
+ /** Handles an update request.
72
+ */
73
+ function update(sid, change_id, callback) {
74
+ var url = base_url + 'edit/' + sid;
75
+ if (change_id) {
76
+ url = url + '/' + change_id;
77
+ } else {
78
+ url = url + '/0';
79
+ }
80
+ console.log("logging info: %o", url);
81
+ $.ajax({
82
+ url: url,
83
+ type: 'GET',
84
+ dataType: 'text',
85
+ success: function (resp, textStatus) {
86
+ resp = YAML.eval(resp);
87
+ console.log("update: success: %o - %o", resp, textStatus);
88
+ if (resp) {
89
+ callback(resp);
90
+ } else {
91
+ callback(null);
92
+ }
93
+ },
94
+ error: function (jqXHR, textStatus, errorThrown) {
95
+ console.error("update: failure: %o - %o - %o", jqXHR, textStatus, errorThrown);
96
+ console.log('narf4');
97
+ callback({ error: "Unable to get update from Iated" });
98
+ }
99
+ });
100
+ }
101
+
102
+ /* Main */
103
+ init();
104
+
105
+ /* EOF */
File without changes
@@ -0,0 +1,110 @@
1
+ var is_focused = true;
2
+ var focus_queue = [];
3
+
4
+ /** jQuery plugin to assign unique ids.
5
+ */
6
+ (function( $ ){
7
+ var last_id = 0;
8
+ $.fn.getId = function() {
9
+ var el = this.first();
10
+ if (!el.attr('id')) {
11
+ el.attr('id', 'iat-' + (++last_id));
12
+ }
13
+ return el.attr('id');
14
+ };
15
+ })( jQuery );
16
+
17
+ /** Scan the page for textareas and setup the buttons.
18
+ */
19
+ function init() {
20
+ console.debug('IAT is loading...');
21
+ $('textarea').each(function () {
22
+ var jel = $(this), tid = jel.getId(), button = $('<button class="iat">IAT</button>');
23
+ ;
24
+ jel.after(button);
25
+
26
+ button
27
+ .css('position', 'absolute')
28
+ .click(function (event) {
29
+ edit(jel);
30
+ return false;
31
+ });
32
+ });
33
+ console.debug('IAT is loaded.');
34
+
35
+ $(window).focus(function () {
36
+ is_focused = true;
37
+ while (focus_queue.length > 0) {
38
+ focus_queue.pop()();
39
+ }
40
+ }).blur(function () {
41
+ is_focused = false;
42
+ });
43
+ }
44
+
45
+ /** Called to edit a textarea.
46
+ * @param jel A single jQuery element.
47
+ */
48
+ function edit(jel) {
49
+ var callback = function (msg) {
50
+ console.debug("IAT edit reply for ", jel, " with ", msg);
51
+ if (msg && msg.error) {
52
+ // Handle the error.
53
+ handleError(msg);
54
+ return;
55
+ }
56
+ monitor(jel, msg.sid, null);
57
+ }
58
+ chrome.extension.sendRequest({ action : 'edit',
59
+ text : jel.val(),
60
+ id : jel.getId(),
61
+ url : window.location.href,
62
+ },
63
+ callback);
64
+ }
65
+
66
+ /** Start monitoring for changes.
67
+ * @param jel A single jQuery element.
68
+ * @param sid The sid for this element.
69
+ */
70
+ function monitor(jel, sid, change_id) {
71
+ var callback = function (msg) {
72
+ new_change_id = (msg && msg.id) ? msg.id : change_id;
73
+ console.debug("monitor callback - sid:%o msg:%o el:%o",
74
+ sid, msg, jel);
75
+ if (msg && msg.error) {
76
+ // Handle the error.
77
+ handleError(msg);
78
+ return;
79
+ }
80
+ if (msg && msg.text && msg.text != jel.val()) {
81
+ jel.val(msg.text);
82
+ jel.effect("highlight", {}, 3 * 1000);
83
+ }
84
+ if (is_focused) {
85
+ setTimeout(function () {
86
+ monitor(jel, sid, new_change_id);
87
+ }, 3000);
88
+ } else {
89
+ focus_queue.push(function () {
90
+ monitor(jel, sid, new_change_id);
91
+ });
92
+ }
93
+ }
94
+ chrome.extension.sendRequest({action : 'update',
95
+ sid : sid,
96
+ change_id : change_id},
97
+ callback);
98
+ }
99
+
100
+ /** Handle errors.
101
+ * @param msg A message object containing information on the error.
102
+ */
103
+ function handleError(msg) {
104
+ alert("ERROR: " + msg.error);
105
+ }
106
+
107
+ /** Main **/
108
+ init();
109
+
110
+ /* EOF */