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,36 @@
1
+ # Using external libraries in your Opal app
2
+
3
+ As described in the getting started docs, opal uses a load path which works
4
+ with sprockets to create a set of locations which opal can require files
5
+ from. If you want to add a directory to this load path, you can add it to
6
+ either the global environment, or a sprockets instance.
7
+
8
+ ### Global Environment
9
+
10
+ In the `Opal` module, a property `paths` is used to hold the load paths which
11
+ `Opal` uses to require files from. You can add a directory to this:
12
+
13
+ ```ruby
14
+ Opal.append_path '../my_lib'
15
+ ```
16
+
17
+ Now, any ruby files in this directory can be discovered.
18
+
19
+ ### Sprockets instances
20
+
21
+ `Opal::Environment` is a subclass of the sprockets environment class which
22
+ can have instance specific paths added to it. This class will inherit all
23
+ global paths, but you can also add your instance paths as:
24
+
25
+ ```ruby
26
+ env = Opal::Environment.new
27
+ env.append_path '../my_lib'
28
+ ```
29
+
30
+ ## with Opal::Builder
31
+
32
+ _WIP_
33
+
34
+ ## With opal-sprockets
35
+
36
+ _WIP_
@@ -0,0 +1,64 @@
1
+ # Promise
2
+
3
+ `Promise` is a class available in the Opal stdlib for helping structure asynchronous code.
4
+
5
+ It can be required inside any Opal applicaton:
6
+
7
+ ```ruby
8
+ require 'promise'
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ This example shows how to use a `HTTP` request from `opal-jquery` from a callback style, into a promise style handler.
14
+
15
+ ```ruby
16
+ def get_json(url)
17
+ promise = Promise.new
18
+
19
+ HTTP.get(url) do |response|
20
+ if response.ok?
21
+ promise.resolve response.json
22
+ else
23
+ promise.reject response
24
+ end
25
+ end
26
+
27
+ promise
28
+ end
29
+
30
+ get_json('/users/1.json').then do |json|
31
+ puts "Got data: #{json}"
32
+ end.fail do |res|
33
+ alert "It didn't work :( #{res}"
34
+ end
35
+ ```
36
+
37
+ A promise can only be resolved or rejected once.
38
+
39
+ ### Chaining Promises
40
+
41
+ Promises become useful when chained together. The prevous example could be extended to get another object from the result of the first request.
42
+
43
+ ```ruby
44
+ get_json('/users/1.json').then do |json|
45
+ get_json("/posts/#{json[:post_id]}.json")
46
+ end.then do |post|
47
+ puts "got post: #{post}"
48
+ end
49
+ ```
50
+
51
+ ### Composing Promises
52
+
53
+ `Promise.when` can be used to wait for more than 1 promise to resolve (or reject). Lets assume we wanted to get 2 different users:
54
+
55
+ ```ruby
56
+ first = get_json '/users/1.json'
57
+ second = get_json '/users/2.json'
58
+
59
+ Promise.when(first, second).then do |user1, user2|
60
+ puts "got users: #{user1}, #{user2}"
61
+ end.fail do
62
+ alert "Something bad happened"
63
+ end
64
+ ```
@@ -0,0 +1,116 @@
1
+ # Opal in a Rails application
2
+
3
+ Add Opal to your Gemfile:
4
+
5
+ ``` ruby
6
+ gem 'opal-rails'
7
+ ```
8
+
9
+ Or to start off with Opal when you build your new Rails app:
10
+
11
+ ```bash
12
+ rails new <app-name> --javascript=opal
13
+ ```
14
+
15
+ ## Basic usage through the asset pipeline
16
+
17
+ ```js
18
+ // app/assets/application.js.rb
19
+
20
+ //= require opal
21
+ //= require opal_ujs
22
+ //= require turbolinks
23
+ //= require_tree .
24
+ ```
25
+
26
+ Opal requires are forwarded to the Asset Pipeline at compile time (similarly to what happens for RubyMotion). You can use either the `.rb` or `.opal` extension:
27
+
28
+ ```ruby
29
+ # app/assets/javascripts/greeter.js.rb
30
+
31
+ puts "G'day world!" # check the console!
32
+
33
+ # Dom manipulation
34
+ require 'opal-jquery'
35
+
36
+ Document.ready? do
37
+ Element.find('body > header').html = '<h1>Hi there!</h1>'
38
+ end
39
+ ```
40
+
41
+
42
+
43
+
44
+ ### As a template
45
+
46
+ You can use it for your views too, it even inherits instance and local variables from actions:
47
+
48
+ ```ruby
49
+ # app/controllers/posts_controller.rb
50
+
51
+ def create
52
+ @post = Post.create!(params[:post])
53
+ render type: :js, locals: {comments_html: render_to_string(@post.comments)}
54
+ end
55
+ ```
56
+
57
+ Each assign is filtered through JSON so it's reduced to basic types:
58
+
59
+ ```ruby
60
+ # app/views/posts/create.js.opal
61
+
62
+ post = Element.find('.post')
63
+ post.find('.title').html = @post[:title]
64
+ post.find('.body').html = @post[:body]
65
+ post.find('.comments').html = comments_html
66
+ ```
67
+
68
+
69
+ ### As a Haml filter (optional)
70
+
71
+ Of course you need to require `haml-rails` separately since its presence is not assumed
72
+
73
+ ```haml
74
+ -# app/views/posts/show.html.haml
75
+
76
+ %article.post
77
+ %h1.title= post.title
78
+ .body= post.body
79
+
80
+ %a#show-comments Display Comments!
81
+
82
+ .comments(style="display:none;")
83
+ - post.comments.each do |comment|
84
+ .comment= comment.body
85
+
86
+ :opal
87
+ Document.ready? do
88
+ Element.find('#show-comments').on :click do |click|
89
+ click.prevent_default
90
+ click.current_target.hide
91
+ Element.find('.comments').effect(:fade_in)
92
+ end
93
+ end
94
+ ```
95
+
96
+
97
+ ### Spec!
98
+
99
+ Add specs into `app/assets/javascripts/spec`:
100
+
101
+ and then a spec folder with you specs!
102
+
103
+ ```ruby
104
+ # app/assets/javascripts/spec/example_spec.js.rb
105
+
106
+ describe 'a spec' do
107
+ it 'has successful examples' do
108
+ 'I run'.should =~ /run/
109
+ end
110
+ end
111
+ ```
112
+
113
+ Then visit `/opal_spec` from your app and **reload at will**.
114
+
115
+ ![1 examples, 0 failures](http://f.cl.ly/items/001n0V0g0u0v14160W2G/Schermata%2007-2456110%20alle%201.06.29%20am.png)
116
+
@@ -0,0 +1,98 @@
1
+ # RSpec
2
+
3
+ `opal-rspec` allows opal to use rspec for running specs in javascript
4
+ environments. It comes with built-in support for running rspec with custom
5
+ `phantomjs` and standard web browser formatters. Also, async spec examples
6
+ are supported to reflect browser usage of ruby applications.
7
+
8
+ ```ruby
9
+ describe User do
10
+ it "can be created with a name" do
11
+ expect(User.new).to_not be_persisted
12
+ end
13
+ end
14
+ ```
15
+
16
+ ### Installation
17
+
18
+ Add the `opal-rspec` gem to your Gemfile:
19
+
20
+ ```ruby
21
+ # Gemfile
22
+ gem 'opal'
23
+ gem 'opal-rspec'
24
+ ```
25
+
26
+ ## Running specs
27
+
28
+ ### phantomjs
29
+
30
+ To run specs, a rake task can be added which will load all spec files
31
+ from `spec/`:
32
+
33
+ ```ruby
34
+ # Rakefile
35
+ require 'opal/rspec/rake_task'
36
+ Opal::RSpec::RakeTask.new(:default)
37
+ ```
38
+
39
+ Then, to run your specs inside phantomjs, just run the rake task:
40
+
41
+ ```sh
42
+ $ bundle exec rake
43
+ ```
44
+
45
+ ### In a Browser
46
+
47
+ `opal-rspec` can use sprockets to build and serve specs over a simple rack server. Add the following to a `config.ru` file:
48
+
49
+ ```ruby
50
+ # config.ru
51
+ require 'bundler'
52
+ Bundler.require
53
+
54
+ run Opal::Server.new { |s|
55
+ s.main = 'opal/rspec/sprockets_runner'
56
+ s.append_path 'spec'
57
+ s.debug = false
58
+ }
59
+ ```
60
+
61
+ Then run the rack server bundle exec rackup and visit `http://localhost:9292` in any web browser.
62
+
63
+ ## Async examples
64
+
65
+ `opal-rspec` adds support for async specs to rspec. These specs are defined using
66
+ `#async` instead of `#it`:
67
+
68
+ ```ruby
69
+ describe MyClass do
70
+ # normal example
71
+ it 'does something' do
72
+ expect(:foo).to eq(:foo)
73
+ end
74
+
75
+ # async example
76
+ async 'does something else, too' do
77
+ # ...
78
+ end
79
+ end
80
+ ```
81
+
82
+ This just marks the example as running async. To actually handle the async result,
83
+ you also need to use a `run_async` call inside some future handler:
84
+
85
+ ```ruby
86
+ async 'HTTP requests should work' do
87
+ HTTP.get('/users/1.json') do |res|
88
+ run_async {
89
+ expect(res).to be_ok
90
+ }
91
+ end
92
+ end
93
+ ```
94
+
95
+ The block passed to `run_async` informs the runner that this spec is finished
96
+ so it can move on. Any failures/expectations run inside this block will be run
97
+ in the context of the example.
98
+
@@ -0,0 +1,79 @@
1
+ # Using Opal with Sinatra
2
+
3
+ Add Opal to your Gemfile (or install using `gem`):
4
+
5
+ ```ruby
6
+ # Gemfile
7
+ gem 'sinatra'
8
+ gem 'opal', '~> 0.6.2'
9
+ ```
10
+
11
+ Opal uses `sprockets` as its default build system, so the asset-pipeline
12
+ from rails can be mimicked here to map all ruby assets in the `/assets`
13
+ path to be compiled using opal.
14
+
15
+ ## Basic Application
16
+
17
+ ```ruby
18
+ # config.ru
19
+ require 'opal'
20
+ require 'sinatra'
21
+
22
+ opal = Opal::Server.new {|s|
23
+ s.append_path 'app'
24
+ s.main = 'application'
25
+ }
26
+
27
+ map opal.source_maps.prefix do
28
+ run opal.source_maps
29
+ end
30
+
31
+ map '/assets' do
32
+ run opal.sprockets
33
+ end
34
+
35
+ get '/' do
36
+ <<-HTML
37
+ <!doctype html>
38
+ <html>
39
+ <head>
40
+ <script src="/assets/application.js"></script>
41
+ </head>
42
+ </html>
43
+ HTML
44
+ end
45
+
46
+ run Sinatra::Application
47
+ ```
48
+
49
+ This creates a simple sprockets instance under the `/assets` path. Opal
50
+ uses a set of load paths to compile assets using sprockets. The
51
+ `Opal::Environment` instance is a simple subclass of `Sprockets::Environment`
52
+ with all the custom opal paths added automatically.
53
+
54
+ This `env` object includes all the opal corelib and stdlib paths. To add
55
+ any custom application directories, you must add them to the load path using
56
+ `env.append_path`. You can now add an `app/application.rb` file into this
57
+ added path with some basic content:
58
+
59
+ ```ruby
60
+ # app/application.rb
61
+ require 'opal'
62
+
63
+ puts "wow, running ruby!"
64
+ ```
65
+
66
+ It is necessary to require the opal corelib (seen in the `require` call) above.
67
+ This just makes the Opal runtime and corelib available. Then it is possible to
68
+ use all the corelib methods and classes, e.g. `Kernel#puts` as seen above.
69
+
70
+ ### Running Application
71
+
72
+ As this is just a simple sinatra application, you can run it:
73
+
74
+ ```sh
75
+ $ bundle exec rackup
76
+ ```
77
+
78
+ And point your browser towards `http://localhost:9292/` and view the browser
79
+ debug console. You should see this message printed.
@@ -0,0 +1,49 @@
1
+ # Source maps
2
+
3
+ Source maps are available (on current stable release, v0.6.x) even without explicit support from Sprockets in a sort of hackish way.
4
+
5
+ _As such even if they generally work fine there are some limitations and edge case issues._
6
+
7
+ NOTE: Currently on `master` branch sourcemaps are work-in-progress and probably will integrate with the upcoming Sprockets 4 that has integrated support for them.
8
+
9
+ #### Processor `source_map_enabled` flag
10
+ To enable sourcemaps in the Sprockets processor you need to turn on the relative flag:
11
+
12
+ ```ruby
13
+ Opal::Processor.source_map_enabled = true # default
14
+ ```
15
+
16
+
17
+ #### Sprockets debug mode
18
+
19
+ The sourcemaps only work with Sprockets in debug mode because they are generated just for single files.
20
+
21
+
22
+ ## Enable source maps
23
+
24
+ ### Rails
25
+
26
+ Rails has debug mode already enabled in development environment with the following line from `config/environments/development.rb`:
27
+
28
+ ```ruby
29
+ # Debug mode disables concatenation and preprocessing of assets.
30
+ # This option may cause significant delays in view rendering with a large
31
+ # number of complex assets.
32
+ config.assets.debug = true
33
+ ```
34
+
35
+ `opal-rails` also enables sourcemaps in development so with the standard setup you ready to go.
36
+
37
+
38
+ ### Sinatra
39
+
40
+ You can add `Opal::Server` as in the official example: [sinatra/config.ru](https://github.com/opal/opal/blob/0-6-stable/examples/sinatra/config.ru).
41
+
42
+ ### Opal::Server
43
+
44
+ `Opal::Server` implements sourcemaps and can be used alone or with `Rack::Cascade` in conjunction with other apps.
45
+
46
+ ### Opal::Environment
47
+
48
+ `Opal::Environment` is a bit lower level and doesn't support source maps by itself.
49
+