opal 0.8.0 → 0.8.1.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.
@@ -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
- next
110
- elsif path.directory?
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
@@ -1,5 +1,5 @@
1
1
  module Opal
2
2
  # WHEN RELEASING:
3
3
  # Remember to update RUBY_ENGINE_VERSION in opal/corelib/variables.rb too!
4
- VERSION = '0.8.0'
4
+ VERSION = '0.8.1.rc1'
5
5
  end
@@ -20,5 +20,5 @@ $SAFE = 0
20
20
  RUBY_PLATFORM = 'opal'
21
21
  RUBY_ENGINE = 'opal'
22
22
  RUBY_VERSION = '2.1.5'
23
- RUBY_ENGINE_VERSION = '0.8.0'
23
+ RUBY_ENGINE_VERSION = '0.8.1.rc1'
24
24
  RUBY_RELEASE_DATE = '2015-07-16'
@@ -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.0
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-07-16 00:00:00.000000000 Z
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: '0'
953
+ version: 1.3.1
938
954
  requirements: []
939
955
  rubyforge_project:
940
- rubygems_version: 2.4.6
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