repla 0.3.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.
- 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: []
|