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.
@@ -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