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.
- data/.gitignore +6 -0
- data/Gemfile +3 -0
- data/Guardfile +24 -0
- data/LICENSE +23 -0
- data/Makefile +72 -0
- data/README.md +87 -0
- data/Rakefile +10 -0
- data/bin/iated +13 -0
- data/config.ru +5 -0
- data/extensions/chrome/background.html +5 -0
- data/extensions/chrome/background.js +105 -0
- data/extensions/chrome/contentscript.css +0 -0
- data/extensions/chrome/contentscript.js +110 -0
- data/extensions/chrome/jquery-ui.js +45 -0
- data/extensions/chrome/jquery.js +16 -0
- data/extensions/chrome/jquery.updater.js +46 -0
- data/extensions/chrome/manifest.json +19 -0
- data/extensions/chrome/yaml.js +489 -0
- data/extensions/tests/simple.html +23 -0
- data/features/extension_authenticates.feature +30 -0
- data/features/extension_edits.feature +45 -0
- data/features/step_definitions/extension_steps.rb +134 -0
- data/features/support/env.rb +47 -0
- data/features/support/hooks.rb +11 -0
- data/iated.gemspec +48 -0
- data/lib/iated.rb +111 -0
- data/lib/iated/browser_token_db.rb +76 -0
- data/lib/iated/edit_session.rb +221 -0
- data/lib/iated/helpers.rb +9 -0
- data/lib/iated/mcp.rb +144 -0
- data/lib/iated/page_helpers.rb +33 -0
- data/lib/iated/public/jquery-ui.js +101 -0
- data/lib/iated/public/jquery.js +2 -0
- data/lib/iated/public/robots.txt +5 -0
- data/lib/iated/server.rb +162 -0
- data/lib/iated/sys_pref.rb +201 -0
- data/lib/iated/version.rb +3 -0
- data/lib/iated/views/hello.haml +13 -0
- data/lib/iated/views/preferences.haml +27 -0
- data/lib/iated/views/reference.coffee +79 -0
- data/lib/iated/views/reference.haml +94 -0
- data/lib/iated/views/reference.scss +36 -0
- data/lib/iated/views/root.haml +13 -0
- data/spec/lib/iated/browser_token_db_spec.rb +68 -0
- data/spec/lib/iated/edit_session_spec.rb +157 -0
- data/spec/lib/iated/mcp_spec.rb +86 -0
- data/spec/lib/iated/sys_pref_spec.rb +40 -0
- data/spec/protocol/edit_spec.rb +88 -0
- data/spec/protocol/hello_spec.rb +18 -0
- data/spec/protocol/notfound_spec.rb +11 -0
- data/spec/protocol/ping_spec.rb +10 -0
- data/spec/protocol/preferences_spec.rb +35 -0
- data/spec/spec_helper.rb +21 -0
- metadata +460 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -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.
|
data/Makefile
ADDED
@@ -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
|
data/README.md
ADDED
@@ -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.
|
data/Rakefile
ADDED
data/bin/iated
ADDED
data/config.ru
ADDED
@@ -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 */
|