repla 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/applescript/close_window.scpt +0 -0
- data/lib/applescript/create_window.scpt +0 -0
- data/lib/applescript/do_javascript.scpt +0 -0
- data/lib/applescript/exists.scpt +0 -0
- data/lib/applescript/hide_log.scpt +0 -0
- data/lib/applescript/load_html.scpt +0 -0
- data/lib/applescript/load_html_with_base_url.scpt +0 -0
- data/lib/applescript/load_plugin.scpt +0 -0
- data/lib/applescript/read_from_standard_input.scpt +0 -0
- data/lib/applescript/resource_path_for_plugin.scpt +0 -0
- data/lib/applescript/resource_url_for_plugin.scpt +0 -0
- data/lib/applescript/run_plugin.scpt +0 -0
- data/lib/applescript/run_plugin_in_split.scpt +0 -0
- data/lib/applescript/show_log.scpt +0 -0
- data/lib/applescript/split_id_in_window.scpt +0 -0
- data/lib/applescript/split_id_in_window_last.scpt +0 -0
- data/lib/applescript/toggle_log.scpt +0 -0
- data/lib/applescript/window_id_for_plugin.scpt +0 -0
- data/lib/repla/dependencies/css/style.css +15 -0
- data/lib/repla/dependencies/js/wcdependencies.js +10 -0
- data/lib/repla/dependencies/lib/controller.rb +34 -0
- data/lib/repla/dependencies/lib/model.rb +10 -0
- data/lib/repla/dependencies/lib/tester.rb +19 -0
- data/lib/repla/dependencies/lib/view.rb +19 -0
- data/lib/repla/dependencies/views/view.html.erb +25 -0
- data/lib/repla/dependencies.rb +34 -0
- data/lib/repla/extension_constants.rb +1 -0
- data/lib/repla/lib/constants.rb +11 -0
- data/lib/repla/lib/controller.rb +5 -0
- data/lib/repla/lib/module.rb +133 -0
- data/lib/repla/lib/view/erb.rb +17 -0
- data/lib/repla/lib/view/javascript.rb +45 -0
- data/lib/repla/lib/view/resources.rb +42 -0
- data/lib/repla/lib/view.rb +28 -0
- data/lib/repla/lib/window.rb +75 -0
- data/lib/repla/logger/test/Rakefile +20 -0
- data/lib/repla/logger/test/js/test_view_helper.js +3 -0
- data/lib/repla/logger/test/lib/test_constants.rb +8 -0
- data/lib/repla/logger/test/lib/test_view_helper.rb +27 -0
- data/lib/repla/logger/test/run_tests.sh +3 -0
- data/lib/repla/logger/test/tc_logger.rb +173 -0
- data/lib/repla/logger.rb +69 -0
- data/lib/repla/repl/css/style.css +20 -0
- data/lib/repla/repl/js/wcrepl.js +17 -0
- data/lib/repla/repl/lib/input_controller.rb +18 -0
- data/lib/repla/repl/lib/output_controller.rb +19 -0
- data/lib/repla/repl/lib/view.rb +68 -0
- data/lib/repla/repl/view/view.html.erb +12 -0
- data/lib/repla/repl.rb +49 -0
- data/lib/repla.rb +9 -0
- metadata +92 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1b80e1592a3dc429896f001bda2bddff25b7e3d8
|
4
|
+
data.tar.gz: fdc62f4bd40eee40bd310317e0a69c94aed98c57
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cc65843d273f506f347478d436fbc9ccc12e07f49621be18dba68f2f3428907c349c140e83b2c20c5d6ad70bdb0e3d2e46b727a48ee5b7ebe3130a1e2027144e
|
7
|
+
data.tar.gz: 29484bdba1f0240d71ff699a530a938756f2911473472d9d5efe102da1657d46e3f128b6a77573ced49fce80949932eb18fa1b09b71c2beb5942e4ef440ac7ec
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,15 @@
|
|
1
|
+
body, h5 {
|
2
|
+
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
3
|
+
font-size: 13px;
|
4
|
+
}
|
5
|
+
h5 {
|
6
|
+
font-weight: normal;
|
7
|
+
color: red;
|
8
|
+
}
|
9
|
+
blockquote {
|
10
|
+
margin-left: 2em;
|
11
|
+
}
|
12
|
+
code {
|
13
|
+
background-color: #DBE2EC;
|
14
|
+
font-family: "Menlo", monospace;
|
15
|
+
}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
function addMissingDependency(name, type, installationInstructions) {
|
2
|
+
var source = $("#dependency-template").html();
|
3
|
+
var template = Handlebars.compile(source);
|
4
|
+
var data = {
|
5
|
+
name: name,
|
6
|
+
type: type,
|
7
|
+
installationInstructions: installationInstructions
|
8
|
+
};
|
9
|
+
$(template(data)).appendTo("body");
|
10
|
+
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative 'tester'
|
2
|
+
require_relative 'model'
|
3
|
+
require_relative 'view'
|
4
|
+
|
5
|
+
module Repla::Dependencies
|
6
|
+
|
7
|
+
class Controller < Repla::Controller
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@view = View.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def missing_dependency(dependency)
|
14
|
+
name = dependency.name
|
15
|
+
type = self.class.string_for_type(dependency.type)
|
16
|
+
options = dependency.options
|
17
|
+
if options.has_key?(:installation_instructions)
|
18
|
+
installation_instructions = options[:installation_instructions]
|
19
|
+
end
|
20
|
+
@view.add_missing_dependency(name, type, installation_instructions)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def self.string_for_type(type)
|
26
|
+
case type
|
27
|
+
when :shell_command
|
28
|
+
return "shell command"
|
29
|
+
end
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Repla::Dependencies
|
2
|
+
module Tester
|
3
|
+
def self.check(name, type)
|
4
|
+
case type
|
5
|
+
when :shell_command
|
6
|
+
return check_shell_command(name)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
require 'shellwords'
|
13
|
+
def self.check_shell_command(name)
|
14
|
+
command = "type -a #{Shellwords.escape(name)} > /dev/null 2>&1"
|
15
|
+
system(command)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Repla::Dependencies
|
2
|
+
|
3
|
+
class View < Repla::View
|
4
|
+
BASE_DIRECTORY = File.join(File.dirname(__FILE__), '..')
|
5
|
+
VIEWS_DIRECTORY = File.join(BASE_DIRECTORY, "views")
|
6
|
+
VIEW_TEMPLATE = File.join(VIEWS_DIRECTORY, 'view.html.erb')
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
super
|
10
|
+
self.base_url_path = File.expand_path(BASE_DIRECTORY)
|
11
|
+
load_erb_from_path(VIEW_TEMPLATE)
|
12
|
+
end
|
13
|
+
|
14
|
+
ADD_MISSING_DEPENDENCY_FUNCTION = "addMissingDependency"
|
15
|
+
def add_missing_dependency(name, type, installation_instructions = nil)
|
16
|
+
do_javascript_function(ADD_MISSING_DEPENDENCY_FUNCTION, [name, type, installation_instructions])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8" />
|
5
|
+
<title><%= title %></title>
|
6
|
+
<%= shared_stylesheet_link_tag "raster" %>
|
7
|
+
<link rel="stylesheet" href="css/style.css" />
|
8
|
+
<script id="dependency-template" type="text/x-handlebars-template">
|
9
|
+
<section>
|
10
|
+
<header>
|
11
|
+
<h5>Dependency <span class="type">{{type}}</span> <code class="name">{{name}}</code> not found.</h5>
|
12
|
+
</header>
|
13
|
+
{{#if installationInstructions}}
|
14
|
+
<p><blockquote class="installation">To install <code>{{name}}</code>: {{{installationInstructions}}}</blockquote></p>
|
15
|
+
{{/if}}
|
16
|
+
</section>
|
17
|
+
</script>
|
18
|
+
<%= shared_javascript_include_tag "handlebars" %>
|
19
|
+
<%= shared_javascript_include_tag "zepto" %>
|
20
|
+
<script type="text/javascript" src="js/wcdependencies.js"></script>
|
21
|
+
</head>
|
22
|
+
<body>
|
23
|
+
|
24
|
+
</body>
|
25
|
+
</html>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative 'extension_constants'
|
2
|
+
require REPLA_FILE
|
3
|
+
|
4
|
+
module Repla::Dependencies
|
5
|
+
class Checker
|
6
|
+
require_relative 'dependencies/lib/model'
|
7
|
+
require_relative 'dependencies/lib/controller'
|
8
|
+
|
9
|
+
def check_dependencies(dependencies)
|
10
|
+
passed = true
|
11
|
+
dependencies.each { |dependency|
|
12
|
+
dependency_passed = check(dependency)
|
13
|
+
passed = false unless dependency_passed
|
14
|
+
}
|
15
|
+
passed
|
16
|
+
end
|
17
|
+
|
18
|
+
def check(dependency)
|
19
|
+
name = dependency.name
|
20
|
+
type = dependency.type
|
21
|
+
passed = Tester::check(name, type)
|
22
|
+
controller.missing_dependency(dependency) unless passed
|
23
|
+
passed
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def controller
|
29
|
+
@controller ||= Controller.new
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
REPLA_FILE = File.join(File.dirname(__FILE__), "../repla")
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Repla
|
2
|
+
# Keys
|
3
|
+
PLUGIN_NAME_KEY = 'WC_PLUGIN_NAME'
|
4
|
+
SPLIT_ID_KEY = 'WC_SPLIT_ID'
|
5
|
+
WINDOW_ID_KEY = 'WC_WINDOW_ID'
|
6
|
+
SHARED_RESOURCES_PATH_KEY = 'WC_SHARED_RESOURCES_PATH'
|
7
|
+
SHARED_RESOURCES_URL_KEY = 'WC_SHARED_RESOURCES_URL'
|
8
|
+
|
9
|
+
# Directories
|
10
|
+
APPLESCRIPT_DIRECTORY = File.join(File.dirname(__FILE__), "..", "..", "applescript")
|
11
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'Shellwords'
|
2
|
+
module Repla
|
3
|
+
LOAD_PLUGIN_SCRIPT = File.join(APPLESCRIPT_DIRECTORY, "load_plugin.scpt")
|
4
|
+
def self.load_plugin(path)
|
5
|
+
self.run_applescript(LOAD_PLUGIN_SCRIPT, [path])
|
6
|
+
end
|
7
|
+
|
8
|
+
EXISTS_SCRIPT = File.join(APPLESCRIPT_DIRECTORY, "exists.scpt")
|
9
|
+
def self.application_exists
|
10
|
+
result = self.run_applescript(EXISTS_SCRIPT)
|
11
|
+
result == "true" ? true : false
|
12
|
+
end
|
13
|
+
|
14
|
+
RUN_PLUGIN_SCRIPT = File.join(APPLESCRIPT_DIRECTORY, "run_plugin.scpt")
|
15
|
+
def self.run_plugin(name, directory = nil, arguments = nil)
|
16
|
+
parameters = [name]
|
17
|
+
parameters.push(directory) unless directory.nil?
|
18
|
+
parameters += arguments unless arguments.nil?
|
19
|
+
self.run_applescript(RUN_PLUGIN_SCRIPT, parameters)
|
20
|
+
end
|
21
|
+
|
22
|
+
RUN_PLUGIN_IN_SPLIT_SCRIPT = File.join(APPLESCRIPT_DIRECTORY, "run_plugin_in_split.scpt")
|
23
|
+
def self.run_plugin_in_split(name, window_id, split_id)
|
24
|
+
parameters = [name, window_id, split_id]
|
25
|
+
self.run_applescript(RUN_PLUGIN_IN_SPLIT_SCRIPT, parameters)
|
26
|
+
end
|
27
|
+
|
28
|
+
WINDOW_ID_FOR_PLUGIN_SCRIPT = File.join(APPLESCRIPT_DIRECTORY, "window_id_for_plugin.scpt")
|
29
|
+
def self.window_id_for_plugin(name)
|
30
|
+
self.run_applescript(WINDOW_ID_FOR_PLUGIN_SCRIPT, [name])
|
31
|
+
end
|
32
|
+
|
33
|
+
SPLIT_ID_IN_WINDOW_SCRIPT = File.join(APPLESCRIPT_DIRECTORY, "split_id_in_window.scpt")
|
34
|
+
def self.split_id_in_window(window_id, pluginName = nil)
|
35
|
+
arguments = [window_id]
|
36
|
+
arguments.push(pluginName) unless pluginName.nil?
|
37
|
+
self.run_applescript(SPLIT_ID_IN_WINDOW_SCRIPT, arguments)
|
38
|
+
end
|
39
|
+
|
40
|
+
SPLIT_ID_IN_WINDOW_LAST_SCRIPT = File.join(APPLESCRIPT_DIRECTORY, "split_id_in_window_last.scpt")
|
41
|
+
def self.split_id_in_window_last(window_id)
|
42
|
+
arguments = [window_id]
|
43
|
+
self.run_applescript(SPLIT_ID_IN_WINDOW_LAST_SCRIPT, arguments)
|
44
|
+
end
|
45
|
+
|
46
|
+
CREATE_WINDOW_SCRIPT = File.join(APPLESCRIPT_DIRECTORY, "create_window.scpt")
|
47
|
+
def self.create_window
|
48
|
+
self.run_applescript(CREATE_WINDOW_SCRIPT)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Shared Resources
|
52
|
+
|
53
|
+
RESOURCE_PATH_FOR_PLUGIN_SCRIPT = File.join(APPLESCRIPT_DIRECTORY, "resource_path_for_plugin.scpt")
|
54
|
+
def self.resource_path_for_plugin(name)
|
55
|
+
self.run_applescript(RESOURCE_PATH_FOR_PLUGIN_SCRIPT, [name])
|
56
|
+
end
|
57
|
+
|
58
|
+
# Shared Resource Path
|
59
|
+
|
60
|
+
SHARED_RESOURCES_PLUGIN_NAME = "Shared Resources"
|
61
|
+
SHARED_TEST_RESOURCES_PLUGIN_NAME = "Shared Test Resources"
|
62
|
+
def self.shared_resources_path
|
63
|
+
resource_path_for_plugin(SHARED_RESOURCES_PLUGIN_NAME)
|
64
|
+
end
|
65
|
+
def self.shared_test_resources_path
|
66
|
+
resource_path_for_plugin(SHARED_TEST_RESOURCES_PLUGIN_NAME)
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.shared_resource(resource)
|
70
|
+
File.join(self.shared_resources_path, resource)
|
71
|
+
end
|
72
|
+
def self.shared_test_resource(resource)
|
73
|
+
File.join(self.shared_test_resources_path, resource)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Shared Resource URL
|
77
|
+
|
78
|
+
RESOURCE_URL_FOR_PLUGIN_SCRIPT = File.join(APPLESCRIPT_DIRECTORY, "resource_url_for_plugin.scpt")
|
79
|
+
def self.resource_url_for_plugin(name)
|
80
|
+
self.run_applescript(RESOURCE_URL_FOR_PLUGIN_SCRIPT, [name])
|
81
|
+
end
|
82
|
+
def self.shared_resources_url
|
83
|
+
resource_url_for_plugin(SHARED_RESOURCES_PLUGIN_NAME)
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def self.run_applescript(script, arguments = nil)
|
89
|
+
command = "osascript #{script.shell_escape}"
|
90
|
+
|
91
|
+
if arguments
|
92
|
+
command += " " + arguments.compact.map(&:to_s).map(&:shell_escape).join(' ')
|
93
|
+
end
|
94
|
+
|
95
|
+
result = `#{command}`
|
96
|
+
|
97
|
+
result.chomp!
|
98
|
+
|
99
|
+
return nil if result.empty?
|
100
|
+
return result.to_i if result.is_integer?
|
101
|
+
return result.to_f if result.is_float?
|
102
|
+
|
103
|
+
result
|
104
|
+
end
|
105
|
+
|
106
|
+
class ::String
|
107
|
+
def is_float?
|
108
|
+
true if Float(self) rescue false
|
109
|
+
end
|
110
|
+
|
111
|
+
def is_integer?
|
112
|
+
self.to_i.to_s == self
|
113
|
+
end
|
114
|
+
|
115
|
+
def shell_escape
|
116
|
+
Shellwords.escape(self)
|
117
|
+
end
|
118
|
+
|
119
|
+
def shell_escape!
|
120
|
+
replace(shell_escape)
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
class ::Float
|
126
|
+
alias_method :javascript_argument, :to_s
|
127
|
+
end
|
128
|
+
|
129
|
+
class ::Integer
|
130
|
+
alias_method :javascript_argument, :to_s
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Repla
|
2
|
+
class View < Window
|
3
|
+
|
4
|
+
require 'erb'
|
5
|
+
|
6
|
+
def load_erb_from_path(path)
|
7
|
+
erb = File.new(path).read
|
8
|
+
load_erb(erb)
|
9
|
+
end
|
10
|
+
|
11
|
+
def load_erb(erb)
|
12
|
+
template = ERB.new(erb, nil, '-')
|
13
|
+
html = template.result(binding)
|
14
|
+
load_html(html)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Repla
|
2
|
+
class View < Window
|
3
|
+
|
4
|
+
def do_javascript_function(function, arguments = nil)
|
5
|
+
javascript = self.class.javascript_function(function, arguments)
|
6
|
+
do_javascript(javascript)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.javascript_function(function, arguments = nil)
|
10
|
+
function = function.dup
|
11
|
+
function << '('
|
12
|
+
|
13
|
+
if arguments
|
14
|
+
arguments.each { |argument|
|
15
|
+
if argument
|
16
|
+
function << argument.javascript_argument
|
17
|
+
else
|
18
|
+
function << "null"
|
19
|
+
end
|
20
|
+
function << ', '
|
21
|
+
}
|
22
|
+
function = function[0...-2]
|
23
|
+
end
|
24
|
+
|
25
|
+
function << ');'
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
class ::String
|
31
|
+
def javascript_argument
|
32
|
+
"'#{self.javascript_escape}'"
|
33
|
+
end
|
34
|
+
|
35
|
+
def javascript_escape
|
36
|
+
self.gsub('\\', "\\\\\\\\").gsub("\n", "\\\\n").gsub("'", "\\\\'")
|
37
|
+
end
|
38
|
+
|
39
|
+
def javascript_escape!
|
40
|
+
replace(self.javascript_escape)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Repla
|
2
|
+
class View < Window
|
3
|
+
require 'open-uri'
|
4
|
+
|
5
|
+
require_relative "../constants"
|
6
|
+
require_relative "../module"
|
7
|
+
|
8
|
+
attr_accessor :title
|
9
|
+
|
10
|
+
CSS_EXTENSION = ".css"
|
11
|
+
CSS_PATH_COMPONENT = "css/"
|
12
|
+
def shared_stylesheet_link_tag(resource)
|
13
|
+
uri = URI.join(shared_resources_url, CSS_PATH_COMPONENT, resource + CSS_EXTENSION)
|
14
|
+
stylesheet_link_tag(uri.to_s)
|
15
|
+
end
|
16
|
+
|
17
|
+
def stylesheet_link_tag(url)
|
18
|
+
"<link rel=\"stylesheet\" href=\"#{url}\" />"
|
19
|
+
end
|
20
|
+
|
21
|
+
JS_EXTENSION = ".js"
|
22
|
+
JS_PATH_COMPONENT = "js/"
|
23
|
+
def shared_javascript_include_tag(resource)
|
24
|
+
uri = URI.join(shared_resources_url, JS_PATH_COMPONENT, resource + JS_EXTENSION)
|
25
|
+
javascript_include_tag(uri.to_s)
|
26
|
+
end
|
27
|
+
|
28
|
+
def javascript_include_tag(url)
|
29
|
+
"<script type=\"text/javascript\" src=\"#{url}\"></script>"
|
30
|
+
end
|
31
|
+
|
32
|
+
def title
|
33
|
+
@title ||= ENV.has_key?(PLUGIN_NAME_KEY) ? ENV[PLUGIN_NAME_KEY] : nil
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def shared_resources_url
|
39
|
+
@shared_resources_url || ENV.has_key?(SHARED_RESOURCES_URL_KEY) ? ENV[SHARED_RESOURCES_URL_KEY] : Repla::shared_resources_url
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require_relative "window"
|
2
|
+
require_relative "view/javascript"
|
3
|
+
require_relative "view/erb"
|
4
|
+
require_relative "view/resources"
|
5
|
+
|
6
|
+
module Repla
|
7
|
+
class View < Window
|
8
|
+
|
9
|
+
# Properties
|
10
|
+
def initialize(window_id = nil, view_id = nil)
|
11
|
+
super(window_id)
|
12
|
+
@view_id = view_id
|
13
|
+
end
|
14
|
+
|
15
|
+
def view_id
|
16
|
+
@view_id ||= ENV.has_key?(SPLIT_ID_KEY) ? ENV[SPLIT_ID_KEY] : split_id
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# Web
|
22
|
+
|
23
|
+
def arguments_with_target(arguments)
|
24
|
+
super(arguments).push(view_id)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Repla
|
2
|
+
class Window
|
3
|
+
require_relative "constants"
|
4
|
+
|
5
|
+
attr_writer :base_url
|
6
|
+
|
7
|
+
def initialize(window_id = nil)
|
8
|
+
@window_id = window_id
|
9
|
+
end
|
10
|
+
|
11
|
+
# Properties
|
12
|
+
|
13
|
+
def base_url_path=(value)
|
14
|
+
@base_url = "file://" + value
|
15
|
+
end
|
16
|
+
|
17
|
+
def window_id
|
18
|
+
@window_id ||= ENV.has_key?(WINDOW_ID_KEY) ? ENV[WINDOW_ID_KEY] : Repla::create_window
|
19
|
+
end
|
20
|
+
|
21
|
+
# Web
|
22
|
+
|
23
|
+
LOADHTML_SCRIPT = File.join(APPLESCRIPT_DIRECTORY, "load_html.scpt")
|
24
|
+
LOADHTMLWITHBASEURL_SCRIPT = File.join(APPLESCRIPT_DIRECTORY, "load_html_with_base_url.scpt")
|
25
|
+
def load_html(html)
|
26
|
+
arguments = [html]
|
27
|
+
|
28
|
+
script = LOADHTML_SCRIPT
|
29
|
+
|
30
|
+
if @base_url
|
31
|
+
script = LOADHTMLWITHBASEURL_SCRIPT
|
32
|
+
arguments.push(@base_url)
|
33
|
+
end
|
34
|
+
|
35
|
+
run_script(script, arguments)
|
36
|
+
end
|
37
|
+
|
38
|
+
DOJAVASCRIPT_SCRIPT = File.join(APPLESCRIPT_DIRECTORY, "do_javascript.scpt")
|
39
|
+
def do_javascript(javascript)
|
40
|
+
run_script(DOJAVASCRIPT_SCRIPT, [javascript])
|
41
|
+
end
|
42
|
+
|
43
|
+
READ_FROM_STANDARD_INPUT_SCRIPT = File.join(APPLESCRIPT_DIRECTORY, "read_from_standard_input.scpt")
|
44
|
+
def read_from_standard_input(text)
|
45
|
+
run_script(READ_FROM_STANDARD_INPUT_SCRIPT, [text])
|
46
|
+
end
|
47
|
+
|
48
|
+
# Window
|
49
|
+
|
50
|
+
CLOSEWINDOW_SCRIPT = File.join(APPLESCRIPT_DIRECTORY, "close_window.scpt")
|
51
|
+
def close
|
52
|
+
Repla::run_applescript(CLOSEWINDOW_SCRIPT, [window_id])
|
53
|
+
end
|
54
|
+
|
55
|
+
def split_id
|
56
|
+
Repla::split_id_in_window(window_id)
|
57
|
+
end
|
58
|
+
|
59
|
+
def split_id_last
|
60
|
+
Repla::split_id_in_window_last(window_id)
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def run_script(script, arguments = [])
|
66
|
+
arguments = arguments_with_target(arguments)
|
67
|
+
Repla::run_applescript(script, arguments)
|
68
|
+
end
|
69
|
+
|
70
|
+
def arguments_with_target(arguments)
|
71
|
+
arguments.push(window_id)
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'shellwords'
|
2
|
+
require 'repla'
|
3
|
+
require Repla::shared_test_resource("ruby/test_constants")
|
4
|
+
require Repla::Tests::TEST_HELPER_FILE
|
5
|
+
|
6
|
+
task :default => ['logger:tests']
|
7
|
+
|
8
|
+
namespace :logger do
|
9
|
+
|
10
|
+
task :tests => [:clean_up]
|
11
|
+
|
12
|
+
task :test_logger do
|
13
|
+
logger_tests_file = File.join(File.dirname(__FILE__), "tc_logger.rb")
|
14
|
+
ruby Shellwords.escape(logger_tests_file)
|
15
|
+
end
|
16
|
+
|
17
|
+
task :clean_up => [:test_logger] do
|
18
|
+
Repla::Tests::Helper::quit
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require_relative "../../../extension_constants"
|
2
|
+
|
3
|
+
TEST_CLASS_JAVASCRIPT = "document.body.lastChild.classList[0]"
|
4
|
+
TEST_MESSAGE_JAVASCRIPT = "document.body.lastChild.innerText"
|
5
|
+
TEST_MESSAGE_COUNT_JAVASCRIPT = "document.body.children.length"
|
6
|
+
|
7
|
+
TEST_JAVASCRIPT_DIRECTORY = File.join(File.dirname(__FILE__), "..", "js")
|
8
|
+
TEST_JAVASCRIPT_FILE = File.join(TEST_JAVASCRIPT_DIRECTORY, "test_view_helper.js")
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative 'test_constants'
|
2
|
+
|
3
|
+
class TestViewHelper
|
4
|
+
|
5
|
+
def initialize(window_id, view_id)
|
6
|
+
@view = Repla::View.new(window_id, view_id)
|
7
|
+
javascript = File.read(TEST_JAVASCRIPT_FILE)
|
8
|
+
@view.do_javascript(javascript)
|
9
|
+
end
|
10
|
+
|
11
|
+
def log_message_at_index(index)
|
12
|
+
@view.do_javascript_function('innerTextOfBodyChildAtIndex', [index])
|
13
|
+
end
|
14
|
+
|
15
|
+
def number_of_log_messages
|
16
|
+
@view.do_javascript(TEST_MESSAGE_COUNT_JAVASCRIPT)
|
17
|
+
end
|
18
|
+
|
19
|
+
def last_log_message
|
20
|
+
@view.do_javascript(TEST_MESSAGE_JAVASCRIPT)
|
21
|
+
end
|
22
|
+
|
23
|
+
def last_log_class
|
24
|
+
@view.do_javascript(TEST_CLASS_JAVASCRIPT)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
#!/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/bin/ruby
|
2
|
+
|
3
|
+
require "test/unit"
|
4
|
+
|
5
|
+
require_relative "lib/test_constants"
|
6
|
+
require REPLA_FILE
|
7
|
+
require Repla::shared_test_resource("ruby/test_constants")
|
8
|
+
require Repla::Tests::TEST_HELPER_FILE
|
9
|
+
|
10
|
+
require_relative "lib/test_view_helper"
|
11
|
+
require_relative "../../logger"
|
12
|
+
|
13
|
+
|
14
|
+
class TestConstants < Test::Unit::TestCase
|
15
|
+
|
16
|
+
def test_constants
|
17
|
+
message_prefix = Repla::Logger::MESSAGE_PREFIX
|
18
|
+
assert_not_nil(message_prefix, "The message prefix should not be nil.")
|
19
|
+
error_prefix = Repla::Logger::ERROR_PREFIX
|
20
|
+
assert_not_nil(message_prefix, "The error prefix should not be nil.")
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
class TestUnintializedLogger < Test::Unit::TestCase
|
27
|
+
|
28
|
+
def teardown
|
29
|
+
Repla::Tests::Helper::quit
|
30
|
+
assert(!Repla::Tests::Helper::is_running, "The application should not be running.")
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_uninitialized_logger
|
34
|
+
logger = Repla::Logger.new
|
35
|
+
|
36
|
+
# Test Message
|
37
|
+
message = "Testing log message"
|
38
|
+
logger.info(message)
|
39
|
+
sleep Repla::Tests::TEST_PAUSE_TIME # Pause for output to be processed
|
40
|
+
|
41
|
+
# Make sure the log messages before accessing the logger's `view_id` and `window_id` because those run the logger.
|
42
|
+
# This test should test logging a message and running the logger itself simultaneously.
|
43
|
+
# This is why the `TestViewHelper` is intialized after logging the message.
|
44
|
+
test_view_helper = TestViewHelper.new(logger.window_id, logger.view_id)
|
45
|
+
|
46
|
+
test_message = test_view_helper.last_log_message
|
47
|
+
assert_equal(message, test_message, "The messages should match")
|
48
|
+
test_class = test_view_helper.last_log_class
|
49
|
+
assert_equal("message", test_class, "The classes should match")
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
class TestLogger < Test::Unit::TestCase
|
57
|
+
|
58
|
+
def setup
|
59
|
+
@logger = Repla::Logger.new
|
60
|
+
@logger.show
|
61
|
+
@test_view_helper = TestViewHelper.new(@logger.window_id, @logger.view_id)
|
62
|
+
end
|
63
|
+
|
64
|
+
def teardown
|
65
|
+
Repla::Tests::Helper::quit
|
66
|
+
assert(!Repla::Tests::Helper::is_running, "The application should not be running.")
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_logger
|
70
|
+
test_count = 0
|
71
|
+
|
72
|
+
# Test Error
|
73
|
+
message = "Testing log error"
|
74
|
+
@logger.error(message)
|
75
|
+
sleep Repla::Tests::TEST_PAUSE_TIME # Pause for output to be processed
|
76
|
+
test_message = @test_view_helper.last_log_message
|
77
|
+
assert_equal(message, test_message, "The messages should match")
|
78
|
+
test_class = @test_view_helper.last_log_class
|
79
|
+
assert_equal("error", test_class, "The classes should match")
|
80
|
+
result_count = @test_view_helper.number_of_log_messages
|
81
|
+
test_count += 1
|
82
|
+
assert_equal(test_count, result_count, "The number of log messages should match")
|
83
|
+
|
84
|
+
# Test Message
|
85
|
+
message = "Testing log message"
|
86
|
+
@logger.info(message)
|
87
|
+
sleep Repla::Tests::TEST_PAUSE_TIME # Pause for output to be processed
|
88
|
+
test_message = @test_view_helper.last_log_message
|
89
|
+
assert_equal(message, test_message, "The messages should match")
|
90
|
+
test_class = @test_view_helper.last_log_class
|
91
|
+
assert_equal("message", test_class, "The classes should match")
|
92
|
+
result_count = @test_view_helper.number_of_log_messages
|
93
|
+
test_count += 1
|
94
|
+
assert_equal(test_count, result_count, "The number of log messages should match")
|
95
|
+
|
96
|
+
# Test Only Error Prefix
|
97
|
+
message = Repla::Logger::ERROR_PREFIX.rstrip # Note the trailing whitespace is trimmed
|
98
|
+
@logger.info(message)
|
99
|
+
sleep Repla::Tests::TEST_PAUSE_TIME # Pause for output to be processed
|
100
|
+
test_message = @test_view_helper.last_log_message
|
101
|
+
assert_equal(message, test_message, "The messages should match")
|
102
|
+
test_class = @test_view_helper.last_log_class
|
103
|
+
assert_equal("message", test_class, "The classes should match")
|
104
|
+
result_count = @test_view_helper.number_of_log_messages
|
105
|
+
test_count += 1
|
106
|
+
assert_equal(test_count, result_count, "The number of log messages should match")
|
107
|
+
|
108
|
+
# Test Only Message Prefix
|
109
|
+
message = Repla::Logger::MESSAGE_PREFIX.rstrip # Note the trailing whitespace is trimmed
|
110
|
+
@logger.info(message)
|
111
|
+
sleep Repla::Tests::TEST_PAUSE_TIME # Pause for output to be processed
|
112
|
+
test_message = @test_view_helper.last_log_message
|
113
|
+
assert_equal(message, test_message, "The messages should match")
|
114
|
+
test_class = @test_view_helper.last_log_class
|
115
|
+
assert_equal("message", test_class, "The classes should match")
|
116
|
+
result_count = @test_view_helper.number_of_log_messages
|
117
|
+
test_count += 1
|
118
|
+
assert_equal(test_count, result_count, "The number of log messages should match")
|
119
|
+
|
120
|
+
# Test Blank Spaces
|
121
|
+
@logger.info(" \t")
|
122
|
+
sleep Repla::Tests::TEST_PAUSE_TIME # Pause for output to be processed
|
123
|
+
test_message = @test_view_helper.last_log_message()
|
124
|
+
assert_equal(message, test_message, "The messages should match")
|
125
|
+
test_class = @test_view_helper.last_log_class()
|
126
|
+
assert_equal("message", test_class, "The classes should match")
|
127
|
+
|
128
|
+
# Test Empty String
|
129
|
+
@logger.info("")
|
130
|
+
sleep Repla::Tests::TEST_PAUSE_TIME # Pause for output to be processed
|
131
|
+
test_message = @test_view_helper.last_log_message()
|
132
|
+
assert_equal(message, test_message, "The messages should match")
|
133
|
+
test_class = @test_view_helper.last_log_class()
|
134
|
+
assert_equal("message", test_class, "The classes should match")
|
135
|
+
|
136
|
+
# TODO: Also add the following tests the `Log.wcplugin`
|
137
|
+
|
138
|
+
# Test Whitespace
|
139
|
+
# White space to the left should be preserved, whitespace to the right should be removed
|
140
|
+
# This test fails because retrieving the `innerText` doesn't preserve whitepace.
|
141
|
+
|
142
|
+
# message = "\t Testing log message"
|
143
|
+
# @logger.info(message + "\t ")
|
144
|
+
# sleep Repla::Tests::TEST_PAUSE_TIME # Pause for output to be processed
|
145
|
+
# test_message = @test_view_helper.last_log_message
|
146
|
+
# assert_equal(message, test_message, "The messages should match")
|
147
|
+
# test_class = @test_view_helper.last_log_class
|
148
|
+
# assert_equal("message", test_class, "The classes should match")
|
149
|
+
# result_count = @test_view_helper.number_of_log_messages
|
150
|
+
# test_count += 1
|
151
|
+
# assert_equal(test_count, result_count, "The number of log messages should match")
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_long_input
|
155
|
+
message = %q(
|
156
|
+
Line 1
|
157
|
+
|
158
|
+
Line 2
|
159
|
+
Line 3
|
160
|
+
)
|
161
|
+
@logger.info(message)
|
162
|
+
sleep Repla::Tests::TEST_PAUSE_TIME * 2 # Pause for output to be processed
|
163
|
+
result_count = @test_view_helper.number_of_log_messages
|
164
|
+
assert_equal(result_count, 3, "The number of log messages should match")
|
165
|
+
|
166
|
+
(1..3).each { |i|
|
167
|
+
result = @test_view_helper.log_message_at_index(i - 1)
|
168
|
+
test_result = "Line #{i}"
|
169
|
+
assert_equal(result, test_result, "The number of log messages should match")
|
170
|
+
}
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
data/lib/repla/logger.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require_relative 'extension_constants'
|
2
|
+
require REPLA_FILE
|
3
|
+
|
4
|
+
module Repla
|
5
|
+
|
6
|
+
class Logger
|
7
|
+
MESSAGE_PREFIX = 'MESSAGE '
|
8
|
+
ERROR_PREFIX = 'ERROR '
|
9
|
+
LOG_PLUGIN_NAME = 'Log'
|
10
|
+
|
11
|
+
# Toggle
|
12
|
+
|
13
|
+
SHOW_LOG_SCRIPT = File.join(APPLESCRIPT_DIRECTORY, "show_log.scpt")
|
14
|
+
def show
|
15
|
+
Repla::run_applescript(SHOW_LOG_SCRIPT, [window_id])
|
16
|
+
end
|
17
|
+
|
18
|
+
HIDE_LOG_SCRIPT = File.join(APPLESCRIPT_DIRECTORY, "hide_log.scpt")
|
19
|
+
def hide
|
20
|
+
Repla::run_applescript(HIDE_LOG_SCRIPT, [window_id])
|
21
|
+
end
|
22
|
+
|
23
|
+
TOGGLE_LOG_SCRIPT = File.join(APPLESCRIPT_DIRECTORY, "toggle_log.scpt")
|
24
|
+
def toggle
|
25
|
+
Repla::run_applescript(TOGGLE_LOG_SCRIPT, [window_id])
|
26
|
+
end
|
27
|
+
|
28
|
+
# Messages
|
29
|
+
|
30
|
+
def info(message)
|
31
|
+
message = message.dup
|
32
|
+
message.gsub!(%r{^}, MESSAGE_PREFIX) # Prefix all lines
|
33
|
+
# Strip trailing white space
|
34
|
+
# Add a line break
|
35
|
+
log_message(message)
|
36
|
+
end
|
37
|
+
|
38
|
+
def error(message)
|
39
|
+
message = message.dup
|
40
|
+
message.gsub!(%r{^}, ERROR_PREFIX)
|
41
|
+
log_message(message)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Properties
|
45
|
+
|
46
|
+
def window_id
|
47
|
+
@window_id ||= ENV.has_key?(WINDOW_ID_KEY) ? ENV[WINDOW_ID_KEY] : Repla::create_window
|
48
|
+
end
|
49
|
+
|
50
|
+
def view_id
|
51
|
+
@view_id ||= Repla::split_id_in_window(window_id, LOG_PLUGIN_NAME)
|
52
|
+
return @view_id unless @view_id.nil?
|
53
|
+
|
54
|
+
@view_id = Repla::split_id_in_window_last(window_id)
|
55
|
+
Repla::run_plugin_in_split(LOG_PLUGIN_NAME, window_id, @view_id)
|
56
|
+
@view_id
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
READ_FROM_STANDARD_INPUT_SCRIPT = File.join(APPLESCRIPT_DIRECTORY, "read_from_standard_input.scpt")
|
62
|
+
def log_message(message)
|
63
|
+
message.rstrip!
|
64
|
+
message += "\n"
|
65
|
+
Repla::run_applescript(READ_FROM_STANDARD_INPUT_SCRIPT, [message, window_id, view_id])
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
body {
|
2
|
+
font-family: "Menlo", monospace;
|
3
|
+
font-size: 13px;
|
4
|
+
}
|
5
|
+
li {
|
6
|
+
list-style: none;
|
7
|
+
white-space: pre-wrap;
|
8
|
+
}
|
9
|
+
pre {
|
10
|
+
position: relative;
|
11
|
+
padding-left: 18px;
|
12
|
+
}
|
13
|
+
pre.output code:before
|
14
|
+
{
|
15
|
+
content: '>';
|
16
|
+
font-weight: bold;
|
17
|
+
left: 7px;
|
18
|
+
position: absolute;
|
19
|
+
opacity: 0.5;
|
20
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
var WcREPL = {
|
2
|
+
addCode: function(code, source) {
|
3
|
+
var template = Handlebars.compile(source);
|
4
|
+
var data = {
|
5
|
+
code: code
|
6
|
+
};
|
7
|
+
return $(template(data)).appendTo("body");
|
8
|
+
},
|
9
|
+
addInput: function(code) {
|
10
|
+
var source = $("#input-template").html();
|
11
|
+
this.addCode(code, source);
|
12
|
+
},
|
13
|
+
addOutput: function(code) {
|
14
|
+
var source = $("#output-template").html();
|
15
|
+
this.addCode(code, source);
|
16
|
+
}
|
17
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Repla::REPL
|
2
|
+
class InputController < Repla::Controller
|
3
|
+
|
4
|
+
attr_accessor :view
|
5
|
+
def initialize(view)
|
6
|
+
@view = view
|
7
|
+
end
|
8
|
+
|
9
|
+
def parse_input(input)
|
10
|
+
input = input.dup
|
11
|
+
input.chomp!
|
12
|
+
if !input.strip.empty? # Ignore empty lines
|
13
|
+
@view.add_input(input)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Repla::REPL
|
2
|
+
class OutputController < Repla::Controller
|
3
|
+
|
4
|
+
attr_accessor :view
|
5
|
+
def initialize(view)
|
6
|
+
@view = view
|
7
|
+
end
|
8
|
+
|
9
|
+
def parse_output(output)
|
10
|
+
output = output.dup
|
11
|
+
output.gsub!(/\x1b[^m]*m/, "") # Remove escape sequences
|
12
|
+
output.chomp!
|
13
|
+
if !output.strip.empty? # Ignore empty lines
|
14
|
+
@view.add_output(output)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Repla::REPL
|
2
|
+
class View < Repla::View
|
3
|
+
|
4
|
+
BASE_DIRECTORY = File.join(File.dirname(__FILE__), "..")
|
5
|
+
VIEWS_DIRECTORY = File.join(BASE_DIRECTORY, "view")
|
6
|
+
VIEW_TEMPLATE = File.join(VIEWS_DIRECTORY, 'view.html.erb')
|
7
|
+
def initialize
|
8
|
+
super
|
9
|
+
self.base_url_path = File.expand_path(BASE_DIRECTORY)
|
10
|
+
load_erb_from_path(VIEW_TEMPLATE)
|
11
|
+
end
|
12
|
+
|
13
|
+
ADD_INPUT_JAVASCRIPT_FUNCTION = "WcREPL.addInput"
|
14
|
+
def add_input(input)
|
15
|
+
do_javascript_function(ADD_INPUT_JAVASCRIPT_FUNCTION, [input])
|
16
|
+
end
|
17
|
+
|
18
|
+
ADD_OUTPUT_JAVASCRIPT_FUNCTION = "WcREPL.addOutput"
|
19
|
+
def add_output(output)
|
20
|
+
do_javascript_function(ADD_OUTPUT_JAVASCRIPT_FUNCTION, [output])
|
21
|
+
end
|
22
|
+
|
23
|
+
# Helpers to allow easy loading of REPL resource even from another base URL
|
24
|
+
|
25
|
+
def repl_header_tags
|
26
|
+
%Q[
|
27
|
+
#{repl_stylesheet_link_tag}
|
28
|
+
#{repl_handlebars_template_tags}
|
29
|
+
#{shared_javascript_include_tag("handlebars")}
|
30
|
+
#{shared_javascript_include_tag("zepto")}
|
31
|
+
#{repl_javascript_include_tag}
|
32
|
+
]
|
33
|
+
end
|
34
|
+
|
35
|
+
def repl_handlebars_template_tags
|
36
|
+
%Q[
|
37
|
+
<script id="output-template" type="text/x-handlebars-template">
|
38
|
+
<pre class="output"><code>{{code}}</code></pre>
|
39
|
+
</script>
|
40
|
+
<script id="input-template" type="text/x-handlebars-template">
|
41
|
+
<pre><code>{{code}}</code></pre>
|
42
|
+
</script>]
|
43
|
+
end
|
44
|
+
|
45
|
+
def repl_stylesheet_link_tag
|
46
|
+
path = File.join(repl_base_resource_path, "css/style.css")
|
47
|
+
url = repl_url_for_path(path)
|
48
|
+
stylesheet_link_tag(url)
|
49
|
+
end
|
50
|
+
|
51
|
+
def repl_javascript_include_tag
|
52
|
+
path = File.join(repl_base_resource_path, "js/wcrepl.js")
|
53
|
+
url = repl_url_for_path(path)
|
54
|
+
javascript_include_tag(url)
|
55
|
+
end
|
56
|
+
|
57
|
+
require 'open-uri'
|
58
|
+
def repl_url_for_path(path)
|
59
|
+
uri = URI::encode(path)
|
60
|
+
"file://" + uri
|
61
|
+
end
|
62
|
+
|
63
|
+
def repl_base_resource_path
|
64
|
+
File.expand_path(File.join(File.dirname(__FILE__), "../"))
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
data/lib/repla/repl.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require_relative 'extension_constants'
|
2
|
+
require REPLA_FILE
|
3
|
+
|
4
|
+
module Repla::REPL
|
5
|
+
require_relative "repl/lib/input_controller"
|
6
|
+
require_relative "repl/lib/output_controller"
|
7
|
+
require_relative "repl/lib/view"
|
8
|
+
|
9
|
+
class Wrapper
|
10
|
+
require 'pty'
|
11
|
+
|
12
|
+
def initialize(command)
|
13
|
+
|
14
|
+
PTY.spawn(command) do |output, input, pid|
|
15
|
+
Thread.new do
|
16
|
+
output.each { |line|
|
17
|
+
output_controller.parse_output(line)
|
18
|
+
}
|
19
|
+
end
|
20
|
+
@input = input
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse_input(input)
|
26
|
+
input_controller.parse_input(input)
|
27
|
+
write_input(input)
|
28
|
+
end
|
29
|
+
|
30
|
+
def write_input(input)
|
31
|
+
@input.write(input)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def input_controller
|
37
|
+
@input_controller ||= InputController.new(view)
|
38
|
+
end
|
39
|
+
|
40
|
+
def output_controller
|
41
|
+
@output_controller ||= OutputController.new(view)
|
42
|
+
end
|
43
|
+
|
44
|
+
def view
|
45
|
+
@view ||= View.new
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
data/lib/repla.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
module Repla
|
2
|
+
require_relative "repla/lib/constants"
|
3
|
+
require_relative "repla/lib/window"
|
4
|
+
require_relative "repla/lib/controller"
|
5
|
+
require_relative "repla/lib/view"
|
6
|
+
require_relative "repla/lib/module"
|
7
|
+
end
|
8
|
+
|
9
|
+
Repla::application_exists || abort("The Web Console application is not installed.")
|
metadata
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: repla
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Roben Kleene
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-07-04 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Bridge from Ruby to AppleScript to control Repla.
|
14
|
+
email: contact@robenkleene.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/applescript/close_window.scpt
|
20
|
+
- lib/applescript/create_window.scpt
|
21
|
+
- lib/applescript/do_javascript.scpt
|
22
|
+
- lib/applescript/exists.scpt
|
23
|
+
- lib/applescript/hide_log.scpt
|
24
|
+
- lib/applescript/load_html.scpt
|
25
|
+
- lib/applescript/load_html_with_base_url.scpt
|
26
|
+
- lib/applescript/load_plugin.scpt
|
27
|
+
- lib/applescript/read_from_standard_input.scpt
|
28
|
+
- lib/applescript/resource_path_for_plugin.scpt
|
29
|
+
- lib/applescript/resource_url_for_plugin.scpt
|
30
|
+
- lib/applescript/run_plugin.scpt
|
31
|
+
- lib/applescript/run_plugin_in_split.scpt
|
32
|
+
- lib/applescript/show_log.scpt
|
33
|
+
- lib/applescript/split_id_in_window.scpt
|
34
|
+
- lib/applescript/split_id_in_window_last.scpt
|
35
|
+
- lib/applescript/toggle_log.scpt
|
36
|
+
- lib/applescript/window_id_for_plugin.scpt
|
37
|
+
- lib/repla.rb
|
38
|
+
- lib/repla/dependencies.rb
|
39
|
+
- lib/repla/dependencies/css/style.css
|
40
|
+
- lib/repla/dependencies/js/wcdependencies.js
|
41
|
+
- lib/repla/dependencies/lib/controller.rb
|
42
|
+
- lib/repla/dependencies/lib/model.rb
|
43
|
+
- lib/repla/dependencies/lib/tester.rb
|
44
|
+
- lib/repla/dependencies/lib/view.rb
|
45
|
+
- lib/repla/dependencies/views/view.html.erb
|
46
|
+
- lib/repla/extension_constants.rb
|
47
|
+
- lib/repla/lib/constants.rb
|
48
|
+
- lib/repla/lib/controller.rb
|
49
|
+
- lib/repla/lib/module.rb
|
50
|
+
- lib/repla/lib/view.rb
|
51
|
+
- lib/repla/lib/view/erb.rb
|
52
|
+
- lib/repla/lib/view/javascript.rb
|
53
|
+
- lib/repla/lib/view/resources.rb
|
54
|
+
- lib/repla/lib/window.rb
|
55
|
+
- lib/repla/logger.rb
|
56
|
+
- lib/repla/logger/test/Rakefile
|
57
|
+
- lib/repla/logger/test/js/test_view_helper.js
|
58
|
+
- lib/repla/logger/test/lib/test_constants.rb
|
59
|
+
- lib/repla/logger/test/lib/test_view_helper.rb
|
60
|
+
- lib/repla/logger/test/run_tests.sh
|
61
|
+
- lib/repla/logger/test/tc_logger.rb
|
62
|
+
- lib/repla/repl.rb
|
63
|
+
- lib/repla/repl/css/style.css
|
64
|
+
- lib/repla/repl/js/wcrepl.js
|
65
|
+
- lib/repla/repl/lib/input_controller.rb
|
66
|
+
- lib/repla/repl/lib/output_controller.rb
|
67
|
+
- lib/repla/repl/lib/view.rb
|
68
|
+
- lib/repla/repl/view/view.html.erb
|
69
|
+
homepage:
|
70
|
+
licenses: []
|
71
|
+
metadata: {}
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - "~>"
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '2.0'
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
requirements: []
|
87
|
+
rubyforge_project:
|
88
|
+
rubygems_version: 2.5.2.3
|
89
|
+
signing_key:
|
90
|
+
specification_version: 4
|
91
|
+
summary: Repla helper gem
|
92
|
+
test_files: []
|