opal 0.8.0 → 0.8.1.rc1
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 +4 -4
- data/.gitignore +3 -0
- data/CHANGELOG.md +10 -0
- data/docs/compiled_ruby.md +425 -0
- data/docs/compiler.md +50 -0
- data/docs/compiler_directives.md +40 -34
- data/docs/configuring_gems.md +148 -0
- data/docs/encoding.md +13 -0
- data/docs/faq.md +17 -0
- data/docs/getting_started.md +30 -0
- data/docs/jquery.md +264 -0
- data/docs/libraries.md +36 -0
- data/docs/promises.md +64 -0
- data/docs/rails.md +116 -0
- data/docs/rspec.md +98 -0
- data/docs/sinatra.md +79 -0
- data/docs/source_maps.md +49 -0
- data/docs/static_applications.md +63 -0
- data/docs/templates.md +150 -0
- data/docs/unsupported_features.md +27 -0
- data/docs/using_sprockets.md +72 -0
- data/lib/opal/sprockets/processor.rb +15 -9
- data/lib/opal/version.rb +1 -1
- data/opal/corelib/variables.rb +1 -1
- data/spec/lib/spec_helper.rb +2 -0
- data/spec/lib/sprockets/processor_spec.rb +11 -0
- metadata +22 -6
- data/lib/opal/sprockets/cache_key_fix.rb +0 -17
@@ -0,0 +1,63 @@
|
|
1
|
+
# Static Building
|
2
|
+
|
3
|
+
`opal` makes it easy to build static opal applications. Opal uses internal load
|
4
|
+
paths to make it easy to handle resolving requirements during building. `opal`
|
5
|
+
forms the basis of rails support, so anything you can do there, you can do
|
6
|
+
standalone as well.
|
7
|
+
|
8
|
+
## Overview
|
9
|
+
|
10
|
+
First, install `opal` adding them to a `Gemfile`:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
# Gemfile
|
14
|
+
gem "opal", "~> 0.7.0"
|
15
|
+
```
|
16
|
+
|
17
|
+
Next, we want to add our main app code. Keep all opal code inside `app/`
|
18
|
+
directory, and edit `app/application.rb`:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
# app/application.rb
|
22
|
+
require "opal"
|
23
|
+
|
24
|
+
puts "Wow, running opal!"
|
25
|
+
```
|
26
|
+
|
27
|
+
You will notice the `require "opal"` line which will automatically include the
|
28
|
+
opal runtime and corelib into our output, giving us access to the `puts()`
|
29
|
+
method.
|
30
|
+
|
31
|
+
To build this, we need the rake task to add our
|
32
|
+
`app/` directory to the load path, and then to build our target file
|
33
|
+
`application.rb` which will be found because it is inside our added load path.
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
# Rakefile
|
37
|
+
require 'opal'
|
38
|
+
|
39
|
+
desc "Build our app to build.js"
|
40
|
+
task :build do
|
41
|
+
Opal.append_path "app"
|
42
|
+
File.binwrite "build.js", Opal::Builder.build("application").to_s
|
43
|
+
end
|
44
|
+
```
|
45
|
+
|
46
|
+
Now, if you run `rake build` you will get the `build.js` output file with our
|
47
|
+
application compiled, with the opal runtime included as well.
|
48
|
+
|
49
|
+
To run the application, lets create a very simple html file:
|
50
|
+
|
51
|
+
```html
|
52
|
+
<!DOCTYPE html>
|
53
|
+
<html>
|
54
|
+
<head>
|
55
|
+
<script src="build.js"></script>
|
56
|
+
</head>
|
57
|
+
<body>
|
58
|
+
</body>
|
59
|
+
</html>
|
60
|
+
```
|
61
|
+
|
62
|
+
Now, open this html file and check the browsers console. You should see our
|
63
|
+
message printed in the console.
|
data/docs/templates.md
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
# Templates with Opal
|
2
|
+
|
3
|
+
Opal includes support for running erb templates on the client. Haml templates
|
4
|
+
can also be used via the `opal-haml` gem.
|
5
|
+
|
6
|
+
## Basic Templates
|
7
|
+
|
8
|
+
If you require `template.rb` from the stdlib, then all compiled templates will
|
9
|
+
be available on the `Template` object. Each compiled template will be an
|
10
|
+
instance of `Template`, which provides a basic standard rendering api to make
|
11
|
+
rendering a uniform method on the client.
|
12
|
+
|
13
|
+
For example, to access a template named `user`:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
require 'template'
|
17
|
+
|
18
|
+
template = Template['user']
|
19
|
+
context = User.new('Ford Prefect')
|
20
|
+
|
21
|
+
puts template.render(context)
|
22
|
+
# => "<div>...</div>"
|
23
|
+
```
|
24
|
+
|
25
|
+
`#render()` will run the template in the given context, and return the result
|
26
|
+
as a string. This is usually a html string, but it can be used for any dynamic
|
27
|
+
content.
|
28
|
+
|
29
|
+
### Registered Templates
|
30
|
+
|
31
|
+
You can get a quick list of all registered templates using `.paths`:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
Template.paths
|
35
|
+
# => [#<Template: 'views/user'>, #<Template: 'login'>]
|
36
|
+
```
|
37
|
+
|
38
|
+
These names are the keys used to access a template:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
Template['login']
|
42
|
+
# => #<Template: 'login'>
|
43
|
+
```
|
44
|
+
|
45
|
+
## Haml templates
|
46
|
+
|
47
|
+
`opal-haml` allows `.haml` templates to be compiled, just like opal compiles
|
48
|
+
ruby code, ready to run on the client.
|
49
|
+
|
50
|
+
To get started, add to your Gemfile:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
# Gemfile
|
54
|
+
gem 'opal'
|
55
|
+
gem 'opal-haml'
|
56
|
+
```
|
57
|
+
|
58
|
+
`opal-haml` simply registers the `.haml` template to be handled under sprockets.
|
59
|
+
This means, that you can simply `require()` a haml template in your code.
|
60
|
+
|
61
|
+
Lets say you have the following simple opal app:
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
# app/application.rb
|
65
|
+
require 'opal'
|
66
|
+
|
67
|
+
class User < Struct.new(:name, :age)
|
68
|
+
end
|
69
|
+
```
|
70
|
+
|
71
|
+
We want to create an instance of the `User` class and render it using a haml
|
72
|
+
template. Lets first create that template as `app/views/user.haml`:
|
73
|
+
|
74
|
+
```haml
|
75
|
+
-# app/views/user.haml
|
76
|
+
.row
|
77
|
+
.col-md-6
|
78
|
+
= self.name
|
79
|
+
.col-md-6
|
80
|
+
= self.age
|
81
|
+
```
|
82
|
+
|
83
|
+
You are nearly ready to go. Lets create a user instance and render the template
|
84
|
+
in the context of that user:
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
# app/application.rb
|
88
|
+
require 'opal'
|
89
|
+
require 'views/user'
|
90
|
+
|
91
|
+
class User < Struct.new(:name, :age)
|
92
|
+
end
|
93
|
+
|
94
|
+
ford = User.new('Ford Prefect', 42)
|
95
|
+
template = Template['views/user']
|
96
|
+
|
97
|
+
puts template.render(ford)
|
98
|
+
```
|
99
|
+
|
100
|
+
Note, when requiring haml templates you do not need to specify the `.haml`
|
101
|
+
extension. This code will print the rendered html to the console. If you
|
102
|
+
check it out, you should see it compiled into something like the following:
|
103
|
+
|
104
|
+
```html
|
105
|
+
<div class="row">
|
106
|
+
<div class="col-md-6">
|
107
|
+
Ford Prefect
|
108
|
+
</div>
|
109
|
+
<div class="col-md-6">
|
110
|
+
42
|
111
|
+
</div>
|
112
|
+
</div>
|
113
|
+
```
|
114
|
+
|
115
|
+
## ERB Templates
|
116
|
+
|
117
|
+
Support for `erb` templates is built in directly to the opal gem and stdlib.
|
118
|
+
There is one caveat though when working with sprockets - it must have the
|
119
|
+
`.opalerb` file extension, instead of `.erb`. This is because sprockets has a
|
120
|
+
built in handler for `.erb` files.
|
121
|
+
|
122
|
+
If we have the same user class as above, create an `app/views/user.opalerb`
|
123
|
+
file:
|
124
|
+
|
125
|
+
```erb
|
126
|
+
<!-- app/views/user.opalerb -->
|
127
|
+
<div class="row">
|
128
|
+
<div class="col-md-3"><%= self.name %></div>
|
129
|
+
</div>
|
130
|
+
```
|
131
|
+
|
132
|
+
Again, you must then require the template (without the `.opalerb` extension):
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
# app/application.rb
|
136
|
+
require 'opal'
|
137
|
+
require 'views/user'
|
138
|
+
```
|
139
|
+
|
140
|
+
And then you can access and render the template:
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
# app/application.rb
|
144
|
+
|
145
|
+
template = Template['views/user']
|
146
|
+
user = User.new('Ford Prefect')
|
147
|
+
|
148
|
+
puts template.render(user)
|
149
|
+
# => "<div class="row">...</div>"
|
150
|
+
```
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Unsupported Features
|
2
|
+
|
3
|
+
Opal does not support some language/runtime features of ruby. These are documented here when possible, as well as the reasons why they are not supported.
|
4
|
+
|
5
|
+
#### Mutable Strings ####
|
6
|
+
|
7
|
+
For performance and ease of runtime features, all strings in Opal are immutable, i.e. `#<<`, `#gsub!`, etc. do not exist. Also, symbols are just strings. There is no class, runtime or feature difference between Symbols and Strings. Their syntaxes can be used interchangeably.
|
8
|
+
|
9
|
+
#### Encodings ####
|
10
|
+
|
11
|
+
Encodings only have a very small implementation inside Opal.
|
12
|
+
|
13
|
+
#### Threads ####
|
14
|
+
|
15
|
+
Javascript does not have a native `Thread` implementation, so they are not present inside Opal. There is a placeholder `Thread` class just to provide some small level of compatibility with libraries that expect it. It does not have any function.
|
16
|
+
|
17
|
+
#### Frozen Objects ####
|
18
|
+
|
19
|
+
Opal does not currently support frozen objects, but has placeholder methods to prevent other libraries breaking when expecting these methods. Opal could support frozen objects in the future once a similar implementation becomes available across Javascript runtimes.
|
20
|
+
|
21
|
+
#### `method_added` and `method_removed` hooks ####
|
22
|
+
|
23
|
+
These are not *currently* supported by Opal, but this is considered a bug and will be implemented soon.
|
24
|
+
|
25
|
+
#### Private, Public and Protected methods ####
|
26
|
+
|
27
|
+
All methods in Opal are defined as `public` to avoid additional runtime overhead. `Module#private` and `Module#protected` exist as just placeholder methods and are no-op methods.
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# Opal & Sprockets
|
2
|
+
|
3
|
+
Opal comes with built-in sprockets support, and provides a simple `Opal::Server`
|
4
|
+
class to make it easy to get a rack server up and running for trying out opal.
|
5
|
+
This server will automatically recompile ruby sources when they change, meaning
|
6
|
+
you just need to refresh your page to autorun.
|
7
|
+
|
8
|
+
## Getting setup
|
9
|
+
|
10
|
+
Add `opal` to a `Gemfile`:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
#Gemfile
|
14
|
+
source 'https://rubygems.org'
|
15
|
+
|
16
|
+
gem 'opal', '>= 0.6.0'
|
17
|
+
```
|
18
|
+
|
19
|
+
And install with `bundle install`.
|
20
|
+
|
21
|
+
We need a directory to hold our opal code, so create `app/` and add a simple
|
22
|
+
demo script to `app/application.rb`:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
# app/application.rb
|
26
|
+
require 'opal'
|
27
|
+
|
28
|
+
puts "hello world"
|
29
|
+
```
|
30
|
+
|
31
|
+
Finally, we need a html page to run, so create `index.html`:
|
32
|
+
|
33
|
+
```html
|
34
|
+
<!DOCTYPE html>
|
35
|
+
<html>
|
36
|
+
<head>
|
37
|
+
<meta charset="utf-8">
|
38
|
+
<title>opal server example</title>
|
39
|
+
<script src="/assets/application.js"></script>
|
40
|
+
</head>
|
41
|
+
<body>
|
42
|
+
</body>
|
43
|
+
</html>
|
44
|
+
```
|
45
|
+
|
46
|
+
## Using Opal::Server
|
47
|
+
|
48
|
+
`Opal::Server` can be run like any rack app, so just add a `config.ru` file:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
# config.ru
|
52
|
+
require 'bundler'
|
53
|
+
Bundler.require
|
54
|
+
|
55
|
+
run Opal::Server.new { |s|
|
56
|
+
s.append_path 'app'
|
57
|
+
|
58
|
+
s.main = 'application'
|
59
|
+
|
60
|
+
s.index_path = 'index.html'
|
61
|
+
}
|
62
|
+
```
|
63
|
+
|
64
|
+
This rack app simply adds our `app/` directory to opal load path, and sets our
|
65
|
+
main file to `application`, which will be found inside `app/`.
|
66
|
+
|
67
|
+
## Running the app
|
68
|
+
|
69
|
+
Run `bundle exec rackup` and visit the page `http://localhost:9292` in any
|
70
|
+
browser. Observe the console to see the printed statement.
|
71
|
+
|
72
|
+
You can just change `app/application.rb` and refresh the page to see any changes.
|
@@ -19,6 +19,15 @@ module Opal
|
|
19
19
|
define_singleton_method("#{config_option}=") { |value| Opal::Config.config[config_option] = value }
|
20
20
|
end
|
21
21
|
|
22
|
+
@@cache_key = nil
|
23
|
+
def self.cache_key
|
24
|
+
@@cache_key ||= ['Opal', Opal::VERSION, Opal::Config.config].to_json.freeze
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.reset_cache_key!
|
28
|
+
@@cache_key = nil
|
29
|
+
end
|
30
|
+
|
22
31
|
def evaluate(context, locals, &block)
|
23
32
|
return super unless context.is_a? ::Sprockets::Context
|
24
33
|
|
@@ -64,7 +73,7 @@ module Opal
|
|
64
73
|
|
65
74
|
def process_requires(requires, context)
|
66
75
|
requires.each do |required|
|
67
|
-
required = required.sub(sprockets_extnames_regexp, '')
|
76
|
+
required = required.to_s.sub(sprockets_extnames_regexp, '')
|
68
77
|
context.require_asset required unless stubbed_files.include? required
|
69
78
|
end
|
70
79
|
end
|
@@ -103,14 +112,11 @@ module Opal
|
|
103
112
|
|
104
113
|
absolute_paths.each do |path|
|
105
114
|
path = Pathname(path)
|
106
|
-
pathname = path.relative_path_from(dirname)
|
107
|
-
|
108
|
-
if name.to_s == file
|
109
|
-
|
110
|
-
|
111
|
-
context.depend_on(path.to_s)
|
112
|
-
else
|
113
|
-
context.require_asset(pathname)
|
115
|
+
pathname = path.relative_path_from(dirname).to_s
|
116
|
+
|
117
|
+
if name.to_s == file then next
|
118
|
+
elsif path.directory? then context.depend_on(path.to_s)
|
119
|
+
else context.require_asset(pathname)
|
114
120
|
end
|
115
121
|
end
|
116
122
|
end
|
data/lib/opal/version.rb
CHANGED
data/opal/corelib/variables.rb
CHANGED
data/spec/lib/spec_helper.rb
CHANGED
@@ -6,4 +6,6 @@ RSpec.configure do |config|
|
|
6
6
|
config.filter_run :focus
|
7
7
|
config.order = 'random'
|
8
8
|
config.before { Opal.instance_variable_set('@paths', nil) }
|
9
|
+
config.before { Opal::Config.reset! if defined? Opal::Config }
|
10
|
+
config.before { Opal::Processor.reset_cache_key! if defined? Opal::Processor }
|
9
11
|
end
|
@@ -64,4 +64,15 @@ describe Opal::Processor do
|
|
64
64
|
code.should match stubbed_file
|
65
65
|
end
|
66
66
|
end
|
67
|
+
|
68
|
+
describe '.cache_key' do
|
69
|
+
it 'can be reset' do
|
70
|
+
Opal::Config.arity_check_enabled = true
|
71
|
+
old_cache_key = described_class.cache_key
|
72
|
+
Opal::Config.arity_check_enabled = false
|
73
|
+
expect(described_class.cache_key).to eq(old_cache_key)
|
74
|
+
described_class.reset_cache_key!
|
75
|
+
expect(described_class.cache_key).not_to eq(old_cache_key)
|
76
|
+
end
|
77
|
+
end
|
67
78
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.1.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Beynon
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sourcemap
|
@@ -225,7 +225,24 @@ files:
|
|
225
225
|
- bin/opal-mspec
|
226
226
|
- bin/opal-repl
|
227
227
|
- config.ru
|
228
|
+
- docs/compiled_ruby.md
|
229
|
+
- docs/compiler.md
|
228
230
|
- docs/compiler_directives.md
|
231
|
+
- docs/configuring_gems.md
|
232
|
+
- docs/encoding.md
|
233
|
+
- docs/faq.md
|
234
|
+
- docs/getting_started.md
|
235
|
+
- docs/jquery.md
|
236
|
+
- docs/libraries.md
|
237
|
+
- docs/promises.md
|
238
|
+
- docs/rails.md
|
239
|
+
- docs/rspec.md
|
240
|
+
- docs/sinatra.md
|
241
|
+
- docs/source_maps.md
|
242
|
+
- docs/static_applications.md
|
243
|
+
- docs/templates.md
|
244
|
+
- docs/unsupported_features.md
|
245
|
+
- docs/using_sprockets.md
|
229
246
|
- examples/rack/.gitignore
|
230
247
|
- examples/rack/Gemfile
|
231
248
|
- examples/rack/app/application.rb
|
@@ -299,7 +316,6 @@ files:
|
|
299
316
|
- lib/opal/regexp_anchors.rb
|
300
317
|
- lib/opal/source_map.rb
|
301
318
|
- lib/opal/sprockets.rb
|
302
|
-
- lib/opal/sprockets/cache_key_fix.rb
|
303
319
|
- lib/opal/sprockets/environment.rb
|
304
320
|
- lib/opal/sprockets/erb.rb
|
305
321
|
- lib/opal/sprockets/path_reader.rb
|
@@ -932,12 +948,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
932
948
|
version: '0'
|
933
949
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
934
950
|
requirements:
|
935
|
-
- - "
|
951
|
+
- - ">"
|
936
952
|
- !ruby/object:Gem::Version
|
937
|
-
version:
|
953
|
+
version: 1.3.1
|
938
954
|
requirements: []
|
939
955
|
rubyforge_project:
|
940
|
-
rubygems_version: 2.4.
|
956
|
+
rubygems_version: 2.4.5.1
|
941
957
|
signing_key:
|
942
958
|
specification_version: 4
|
943
959
|
summary: Ruby runtime and core library for javascript
|