opal-knockout 0.0.1

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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d26bfa3441cd888d0a7a9f2782f043b2a4243b47
4
+ data.tar.gz: 7983b847827d99a7a549bf7bc55be6377e1a002d
5
+ SHA512:
6
+ metadata.gz: 5e532374627813506296ea41d133d833822291e161c86f9e5251c4f4aa2f588751bfc2a01c3f161d636409d3911516a4d9824c90e1d980eb380e914c02ea6c89
7
+ data.tar.gz: 737ff0309ecee3e3b5831d6cbf914a68b1b30b4e8913133cf5da4dd7f41ec128d97eee2e879a75960fdf27d6e39faf30376f5317903ee9d6f1bf875d66994c16
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 patorash
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,125 @@
1
+ # opal-knockout: Knockout.js wrapper for Opal
2
+
3
+ opal-konckout is wraper of knockout.js.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'opal-knockout'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install opal-knockout
18
+
19
+ ## Usage(Rails)
20
+
21
+ ### Gemfile
22
+
23
+ ```ruby:Gemfile
24
+ source 'https://rubygems.org'
25
+
26
+ gem 'opal-knockout'
27
+
28
+ source 'https://rails-assets.org' do
29
+ gem 'rails-assets-knockoutjs', '3.3.0'
30
+ end
31
+ ```
32
+
33
+ ### Opal
34
+
35
+ app/assets/javascripts/user_view_model.rb
36
+
37
+ ```ruby:assets/javascripts/user_view_model.rb
38
+ class User
39
+ attr_accessor :first_name, :last_name
40
+
41
+ def initialize(first_name, last_name)
42
+ self.first_name = first_name
43
+ self.last_name = last_name
44
+ end
45
+ end
46
+
47
+ class UserViewModel < Knockout::ViewModel
48
+ attr_observable :first_name, :last_name
49
+ attr_observable_array :users
50
+ attr_computed :full_name, :show_full_name
51
+
52
+ def initialize(first_name, last_name)
53
+ self.first_name = first_name
54
+ self.last_name = last_name
55
+ end
56
+
57
+ def add_users
58
+ self.users.push(User.new(
59
+ self.first_name.to_s,
60
+ self.last_name.to_s
61
+ )
62
+ )
63
+ clear_form
64
+ end
65
+
66
+ private
67
+ def show_full_name
68
+ "#{first_name.to_s} #{last_name.to_s}"
69
+ end
70
+
71
+ def clear_form
72
+ self.first_name = ''
73
+ self.last_name = ''
74
+ end
75
+ end
76
+ ```
77
+
78
+ app/assets/javascripts/application.rb
79
+
80
+
81
+ ```ruby:assets/javascripts/application.rb
82
+ #= require opal
83
+ #= require knockoutjs
84
+ #= require opal-knockout
85
+ #= require_tree .
86
+ #= require_self
87
+
88
+ $root_view_model = Knockout::RootViewModel.new(
89
+ user: UserViewModel.new('Taro', 'Yamada')
90
+ )
91
+ Knockout.apply_bindings($root_view_model)
92
+ ```
93
+
94
+ ### View
95
+
96
+ app/views/users/index.html.slim
97
+
98
+ ```slim:views/users/index.html.slim
99
+ div data-bind="with: user"
100
+ form
101
+ label
102
+ | First Name
103
+ input type="text" data-bind="textInput: first_name"
104
+ br
105
+ label
106
+ | Last Name
107
+ input type="text" data-bind="textInput: last_name"
108
+ p data-bind="text: full_name"
109
+ button type="button" data-bind="click: $add_users"
110
+
111
+ ul data-bind="foreach: users"
112
+ li
113
+ span data-bind="text: first_name"
114
+ | &nbsp;
115
+ span data-bind="text: last_name"
116
+
117
+ ```
118
+
119
+ ## Contributing
120
+
121
+ 1. Fork it ( https://github.com/patorash/opal-knockout/fork )
122
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
123
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
124
+ 4. Push to the branch (`git push origin my-new-feature`)
125
+ 5. Create a new Pull Request
@@ -0,0 +1,80 @@
1
+ require "bundler/gem_tasks"
2
+
3
+
4
+ # require 'bundler'
5
+ # Bundler.require
6
+ # Bundler::GemHelper.install_tasks
7
+
8
+ require 'opal/rspec/rake_task'
9
+ Opal::RSpec::RakeTask.new(:default) do |s|
10
+ s.index_path = 'spec/knockout/index.html.erb'
11
+ end
12
+
13
+ Opal::RSpec::RakeTask.new(:zepto) do |s|
14
+ s.index_path = 'spec/zepto/index.html.erb'
15
+ end
16
+
17
+ desc "Build build/opal-knockout.js"
18
+ task :dist do
19
+ require 'fileutils'
20
+ FileUtils.mkdir_p 'build'
21
+
22
+ src = Opal::Builder.build('opal-knockout')
23
+ min = uglify src
24
+ gzp = gzip min
25
+
26
+ File.open('build/opal-knockout.js', 'w+') do |out|
27
+ out << src
28
+ end
29
+
30
+ puts "development: #{src.size}, minified: #{min.size}, gzipped: #{gzp.size}"
31
+ end
32
+
33
+ # Used for uglifying source to minify
34
+ def uglify(str)
35
+ IO.popen('uglifyjs', 'r+') do |i|
36
+ i.puts str
37
+ i.close_write
38
+ return i.read
39
+ end
40
+ rescue Errno::ENOENT
41
+ $stderr.puts '"uglifyjs" command not found (install with: "npm install -g uglify-js")'
42
+ nil
43
+ end
44
+
45
+ # Gzip code to check file size
46
+ def gzip(str)
47
+ IO.popen('gzip -f', 'r+') do |i|
48
+ i.puts str
49
+ i.close_write
50
+ return i.read
51
+ end
52
+ rescue Errno::ENOENT
53
+ $stderr.puts '"gzip" command not found, it is required to produce the .gz version'
54
+ nil
55
+ end
56
+
57
+
58
+ namespace :doc do
59
+ doc_repo = Pathname(ENV['DOC_REPO'] || 'gh-pages')
60
+ doc_base = doc_repo.join('doc')
61
+ current_git_release = -> { `git rev-parse --abbrev-ref HEAD`.chomp }
62
+ # template_option = "--template opal --template-path #{doc_repo.join('yard-templates')}"
63
+ template_option = ""
64
+
65
+ directory doc_repo.to_s do
66
+ remote = ENV['DOC_REPO_REMOTE'] || '.'
67
+ sh 'git', 'clone', '-b', 'gh-pages', '--', remote, doc_repo.to_s
68
+ end
69
+
70
+ task :default => doc_repo.to_s do
71
+ git = current_git_release.call
72
+ name = 'api'
73
+ glob = 'opal/**/*.rb'
74
+ command = "yard doc #{glob} #{template_option} "\
75
+ "--readme opal/README.md -o gh-pages/doc/#{git}/#{name}"
76
+ puts command; system command
77
+ end
78
+ end
79
+
80
+ task :doc => 'doc:default'
@@ -0,0 +1,12 @@
1
+ require 'bundler'
2
+ Bundler.require
3
+
4
+ require 'opal-rspec'
5
+ Opal.append_path File.expand_path('../spec', __FILE__)
6
+
7
+ run Opal::Server.new { |s|
8
+ s.main = 'opal/rspec/sprockets_runner'
9
+ s.append_path 'spec'
10
+ s.debug = false
11
+ s.index_path = 'spec/knockout/index.html.erb'
12
+ }
@@ -0,0 +1 @@
1
+ application.js
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'opal', '~> 0.7.2'
4
+ gem 'opal-knockout', path: '..'
5
+ gem 'therubyracer'
6
+
7
+ source 'https://rails-assets.org' do
8
+ gem 'rails-assets-knockoutjs', '3.3.0'
9
+ end
@@ -0,0 +1,15 @@
1
+ # for 0.7.x
2
+ #= require opal
3
+ #= require knockoutjs
4
+ #= require opal-knockout
5
+ #= require_tree .
6
+ #= require_self
7
+
8
+
9
+ user_list_view_model = UserListViewModel.new
10
+ $root_view_model = Knockout::RootViewModel.new(
11
+ user: UserViewModel.new('Bob', 25),
12
+ user_form_view_model: UserFormViewModel.new(user_list_view_model),
13
+ user_list_view_model: user_list_view_model
14
+ )
15
+ Knockout.apply_bindings($root_view_model)
@@ -0,0 +1,9 @@
1
+ class Item
2
+ attr_reader :title, :price, :created_at
3
+
4
+ def initialize(title, price, created_at)
5
+ @title = title
6
+ @price = price
7
+ @created_at = created_at
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ class User
2
+ def initialize(name, age)
3
+ @name = name
4
+ @age = age
5
+ end
6
+ end
@@ -0,0 +1,34 @@
1
+ class UserFormViewModel < Knockout::ViewModel
2
+ attr_observable :name, :age
3
+ attr_computed :data, :show_data
4
+
5
+ def initialize(list_view_model)
6
+ @list_view_model = list_view_model
7
+ self.name = ''
8
+ self.age = 0
9
+ end
10
+
11
+ def add_user_list
12
+ @list_view_model.users.push(User.new(self.name.to_s, self.age.to_s))
13
+ clear_form
14
+ end
15
+
16
+ def increment_age
17
+ if self.age.call.is_a? Integer
18
+ # self.age += 1
19
+ self.age = self.age.call + 1
20
+ else
21
+ self.age = self.age.call.to_i + 1
22
+ end
23
+ end
24
+
25
+ private
26
+ def show_data
27
+ "#{name.to_s}さんは#{age.to_s}歳"
28
+ end
29
+
30
+ def clear_form
31
+ self.name = ''
32
+ self.age = 0
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ class UserListViewModel < Knockout::ViewModel
2
+ attr_observable_array :users
3
+ end
@@ -0,0 +1,49 @@
1
+ class UserViewModel < Knockout::ViewModel
2
+ attr_observable :name, :age
3
+ # attr_observable 12
4
+ attr_observable_array :items, :words
5
+
6
+ attr_computed :hoge do
7
+ self.words.index_of("fghij")
8
+ end
9
+
10
+ attr_computed :foo, :search_fghij
11
+
12
+ def initialize(name=nil, age=nil)
13
+ # `debugger`
14
+
15
+ self.name = name
16
+ self.age = age
17
+ self.items = (1..10).map {|i| Item.new("title_#{i}", i*1000, Time.new(2015,9,i)) }
18
+ # 10.times { |i| self.items.push(Item.new("title_#{i}", i*1000, Time.new(2015,9,i))) }
19
+ # self.items.pop()
20
+ # self.items = self.items.reverse
21
+ self.items.remove_if do |item|
22
+ item.price < 3000
23
+ end
24
+ items = self.items.to_a.first(3)
25
+ self.items.remove(items)
26
+ self.items.reverse
27
+ self.items.push(Item.new("abcde", 4000, Time.new(2015,9,3)))
28
+ self.words = %w(abcde fghij klmno)
29
+ # self.hoge = `ko.computed(function(){ return #{self.words.index_of("fghij")} }, this)`
30
+ # self.hoge = computed do
31
+ # self.words.index_of("fghij")
32
+ # end
33
+ puts self.words.slice(1)
34
+ puts self.words.slice(-1)
35
+ end
36
+
37
+ def increment_age
38
+ self.age += 1
39
+ end
40
+
41
+ def decrement_age
42
+ self.age -= 1
43
+ end
44
+
45
+ private
46
+ def search_fghij
47
+ "#{name.to_s}さんは#{age.to_s}歳です。"
48
+ end
49
+ end
@@ -0,0 +1,10 @@
1
+ require 'bundler'
2
+ Bundler.require
3
+
4
+ run Opal::Server.new { |s|
5
+ RailsAssets.load_paths.each { |p| s.append_path p }
6
+ s.append_path 'app'
7
+ s.main = 'application'
8
+ s.debug = true
9
+ s.index_path = 'index.html.erb'
10
+ }
@@ -0,0 +1,57 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>opal-knockout example</title>
5
+ </head>
6
+ <body>
7
+ <form data-bind="with: user_form_view_model">
8
+ <label>Name: <input type="text" data-bind="textInput: name"></label>
9
+ <label>Age: <input type="number" data-bind="textInput: age"></label>
10
+ <p data-bind="text: data"></p>
11
+ <button type="button" data-bind="click: $increment_age">+</button>
12
+ <button type="button" data-bind="click: $add_user_list">Add list</button>
13
+ </form>
14
+
15
+ <div data-bind="with: user_list_view_model">
16
+ <h3>ユーザーリスト</h3>
17
+ <ul data-bind="foreach: users">
18
+ <li><span data-bind="text: name"></span>さんは<span data-bind="text: age"></span>歳です。</li>
19
+ </ul>
20
+ </div>
21
+
22
+ <div data-bind="with: user">
23
+ <dl>
24
+ <dt>Name:</dt>
25
+ <dd data-bind="text: name"></dd>
26
+ <dt>Age:</dt>
27
+ <dd data-bind="text: age"></dd>
28
+ </dl>
29
+ <button type="button" data-bind="click: $increment_age">
30
+ 加齢
31
+ </button>
32
+ <button type="button" data-bind="click: $decrement_age">
33
+ 減齢
34
+ </button>
35
+
36
+ <table>
37
+ <caption data-bind="text: items.$size()"></caption>
38
+ <tbody data-bind="foreach: items">
39
+ <tr>
40
+ <td data-bind="text: title"></td>
41
+ <td data-bind="text: price"></td>
42
+ <td data-bind="text: created_at"></td>
43
+ </tr>
44
+ </tbody>
45
+ </table>
46
+
47
+ <p>
48
+ hoge result: <span data-bind="text: hoge"></span>
49
+ </p>
50
+ <p>
51
+ foo result: <span data-bind="text: foo"></span>
52
+ </p>
53
+
54
+ </div>
55
+ <%= javascript_include_tag @server.main %>
56
+ </body>
57
+ </html>
@@ -0,0 +1 @@
1
+ require 'opal/knockout'
@@ -0,0 +1,13 @@
1
+ if RUBY_ENGINE == 'opal'
2
+ require 'opal/knockout/observable'
3
+ require 'opal/knockout/observable_array'
4
+ require 'opal/knockout/computed'
5
+ require 'opal/knockout/view_model'
6
+ require 'opal/knockout/root_view_model'
7
+ require 'opal/knockout/knockout'
8
+ else
9
+ require 'opal'
10
+ require 'opal/knockout/version'
11
+
12
+ Opal.append_path File.expand_path('../..', __FILE__).untaint
13
+ end
@@ -0,0 +1,19 @@
1
+ module Knockout
2
+ class Computed
3
+ def initialize(&block)
4
+ @callback = %x{
5
+ ko.computed(function() {
6
+ return #{block.call};
7
+ });
8
+ }
9
+ end
10
+
11
+ def to_s
12
+ @callback.call
13
+ end
14
+
15
+ def to_n
16
+ @callback
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'native'
2
+
3
+ module Knockout
4
+ module ModuleMethods
5
+ def apply_bindings(view_model, element=nil)
6
+ if element.nil?
7
+ if view_model.is_a? Knockout::RootViewModel
8
+ `ko.applyBindings(#{view_model.view_models.to_n})`
9
+ else
10
+ `ko.applyBindings(#{view_model.to_n})`
11
+ end
12
+ else
13
+ `ko.applyBindings(#{view_model.to_n}, #{element})`
14
+ end
15
+ end
16
+ end
17
+
18
+ extend ModuleMethods
19
+ end
@@ -0,0 +1,15 @@
1
+ module Knockout
2
+ module Observable
3
+ def to_s
4
+ `#{self.call} + ''`
5
+ end
6
+
7
+ def +(value)
8
+ self.call.+(value)
9
+ end
10
+
11
+ def -(value)
12
+ self.call.-(value)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,82 @@
1
+ module Knockout
2
+ module ObservableArray
3
+
4
+ def size
5
+ self.to_a.size
6
+ end
7
+
8
+ def to_a
9
+ self.call
10
+ end
11
+
12
+ def push(item)
13
+ `#{self}.push(#{item})`
14
+ end
15
+
16
+ def pop
17
+ `#{self}.pop()`
18
+ end
19
+
20
+ def shift
21
+ `#{self}.shift()`
22
+ end
23
+
24
+ def reverse
25
+ `#{self}.reverse()`
26
+ end
27
+
28
+ def remove(item)
29
+ if item.is_a? Array
30
+ `#{self}.removeAll(#{item})`
31
+ else
32
+ `#{self}.remove(#{item})`
33
+ end
34
+ end
35
+
36
+ def remove_if(&block)
37
+ %x{
38
+ #{self}.remove(function(item) {
39
+ return #{block.call(`item`)};
40
+ });
41
+ }
42
+ end
43
+
44
+ def remove_all
45
+ `#{self}.removeAll()`
46
+ end
47
+
48
+ alias_method :clear, :remove_all
49
+
50
+ def destroy(item)
51
+ if item.is_a? Array
52
+ `#{self}.destroyAll(#{item})`
53
+ else
54
+ `#{self}.destroy(#{item})`
55
+ end
56
+ end
57
+
58
+ def destroy_if(&block)
59
+ %x{
60
+ #{self}.destroy(function(item) {
61
+ return #{block.call(`item`)};
62
+ });
63
+ }
64
+ end
65
+
66
+ def destroy_all
67
+ `#{self}.destroyAll()`
68
+ end
69
+
70
+ def index_of(str)
71
+ `#{self}.indexOf(#{str})`
72
+ end
73
+
74
+ def slice(_start=0, _end=nil)
75
+ if _end.nil?
76
+ `#{self}.slice(#{_start})`
77
+ else
78
+ `#{self}.slice(#{_start}, #{_end})`
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,29 @@
1
+ module Knockout
2
+ class RootViewModel
3
+ attr_accessor :view_models
4
+
5
+ def initialize(view_models=nil)
6
+ self.view_models = {}
7
+ self.add_view_models(view_models) unless view_models.nil?
8
+ end
9
+
10
+ def add_view_model(name, view_model)
11
+ if name.is_a?(String || Symbol) && view_model.is_a?(Knockout::ViewModel)
12
+ self.view_models[name] = view_model
13
+ else
14
+ raise ArgumentError
15
+ end
16
+ end
17
+
18
+ def add_view_models(view_models)
19
+ view_models.each do |name, view_model|
20
+ add_view_model(name, view_model)
21
+ end
22
+ end
23
+
24
+ def find_view_model_by_name(name)
25
+ self.view_models[name]
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,5 @@
1
+ module Opal
2
+ module Knockout
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,106 @@
1
+ module Knockout
2
+ class ViewModel
3
+ class << self
4
+ attr_accessor :_observables
5
+ attr_accessor :_observable_arrays
6
+ attr_accessor :_computed_methods
7
+
8
+ def new( *args, &blk )
9
+ object = allocate
10
+ object.before_initialize
11
+ object.instance_eval{ initialize( *args, &blk ) }
12
+ object.after_initialize
13
+ object
14
+ end
15
+
16
+ def attr_observable(*names)
17
+ names.each { |name| define_observable_accessor(name) }
18
+ end
19
+
20
+ def attr_observable_array(*names)
21
+ names.each { |name| define_observable_array_accessor(name) }
22
+ end
23
+
24
+ def attr_computed(name, method_name=nil, &block)
25
+ raise ArgumentError, "#{self.to_s}##{__method__}: You must set method_name or block" if method_name.nil? && !block_given?
26
+ return if method_name.nil? && !block_given?
27
+ self._computed_methods ||= {}
28
+ self._computed_methods[name] = if method_name.nil?
29
+ block
30
+ else
31
+ method_name
32
+ end
33
+ end
34
+
35
+ private
36
+ def define_observable_accessor(name)
37
+ raise ArgumentError, "#{self.to_s}##{__method__}: name must String or Symbol" unless name.is_a?(String) || name.is_a?(Symbol)
38
+ self._observables ||= []
39
+ self._observables << name
40
+
41
+ define_method name do
42
+ instance_variable_get(:"@#{name}")
43
+ end
44
+
45
+ define_method "#{name}=" do |value|
46
+ instance_variable_get(:"@#{name}").call(value)
47
+ end
48
+ end
49
+
50
+ def define_observable_array_accessor(name)
51
+ raise ArgumentError, "#{self.to_s}##{__method__}: name must String or Symbol" unless name.is_a?(String) || name.is_a?(Symbol)
52
+ self._observable_arrays ||= []
53
+ self._observable_arrays << name
54
+
55
+ define_method name do
56
+ instance_variable_get(:"@#{name}")
57
+ end
58
+
59
+ define_method "#{name}=" do |value|
60
+ instance_variable_get(:"@#{name}").call(value)
61
+ end
62
+ end
63
+ end
64
+
65
+ private
66
+ def before_initialize
67
+ set_observables
68
+ set_observable_arrays
69
+ end
70
+
71
+ def after_initialize
72
+ set_computed_variables
73
+ end
74
+
75
+ def set_observables
76
+ (self.class._observables || []).each do |name|
77
+ observable = `ko.observable()`
78
+ observable.instance_eval do
79
+ extend Knockout::Observable
80
+ end
81
+ instance_variable_set(:"@#{name}", observable)
82
+ end
83
+ end
84
+
85
+ def set_observable_arrays
86
+ (self.class._observable_arrays || []).each do |name|
87
+ observable_array = `ko.observableArray()`
88
+ observable_array.instance_eval do
89
+ extend Knockout::ObservableArray
90
+ end
91
+ instance_variable_set(:"@#{name}", observable_array)
92
+ end
93
+ end
94
+
95
+ def set_computed_variables
96
+ (self.class._computed_methods || {}).each do |name, method_name|
97
+ if method_name.is_a? Proc
98
+ block = method_name
99
+ instance_variable_set(:"@#{name}", Knockout::Computed.new{ self.instance_eval(&block) } )
100
+ else
101
+ instance_variable_set(:"@#{name}", Knockout::Computed.new{ self.method(method_name).call } )
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'opal/knockout/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "opal-knockout"
8
+ spec.version = Opal::Knockout::VERSION
9
+ spec.authors = ["patorash"]
10
+ spec.email = ["chariderpato@gmail.com"]
11
+ spec.summary = %q{Opal library for knockout.js}
12
+ spec.description = %q{Opal library for knockout.js}
13
+ spec.homepage = "https://github.com/patorash/opal-knockout"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_runtime_dependency 'opal', '>= 0.7.0', '< 0.9.0'
23
+ spec.add_development_dependency 'opal-jquery', '~> 0.4.0'
24
+ spec.add_development_dependency 'opal-rspec', '~> 0.4.0'
25
+ spec.add_development_dependency 'yard'
26
+ spec.add_development_dependency 'rake'
27
+ end
@@ -0,0 +1,8 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ </head>
5
+ <body>
6
+ <%= javascript_include_tag @server.main %>
7
+ </body>
8
+ </html>
@@ -0,0 +1,3 @@
1
+ require 'opal-rspec'
2
+ require 'opal/knockout'
3
+ require 'opal/knockout/rspec'
metadata ADDED
@@ -0,0 +1,165 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: opal-knockout
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - patorash
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-09-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: opal
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.7.0
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: 0.9.0
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.7.0
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: 0.9.0
47
+ - !ruby/object:Gem::Dependency
48
+ name: opal-jquery
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: 0.4.0
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: 0.4.0
61
+ - !ruby/object:Gem::Dependency
62
+ name: opal-rspec
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: 0.4.0
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 0.4.0
75
+ - !ruby/object:Gem::Dependency
76
+ name: yard
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rake
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ description: Opal library for knockout.js
104
+ email:
105
+ - chariderpato@gmail.com
106
+ executables: []
107
+ extensions: []
108
+ extra_rdoc_files: []
109
+ files:
110
+ - ".gitignore"
111
+ - Gemfile
112
+ - LICENSE.txt
113
+ - README.md
114
+ - Rakefile
115
+ - config.ru
116
+ - example/.gitignore
117
+ - example/Gemfile
118
+ - example/app/application.rb
119
+ - example/app/item.rb
120
+ - example/app/user.rb
121
+ - example/app/user_form_view_model.rb
122
+ - example/app/user_list_view_model.rb
123
+ - example/app/user_view_model.rb
124
+ - example/config.ru
125
+ - example/index.html.erb
126
+ - lib/opal-knockout.rb
127
+ - lib/opal/knockout.rb
128
+ - lib/opal/knockout/computed.rb
129
+ - lib/opal/knockout/knockout.rb
130
+ - lib/opal/knockout/observable.rb
131
+ - lib/opal/knockout/observable_array.rb
132
+ - lib/opal/knockout/root_view_model.rb
133
+ - lib/opal/knockout/version.rb
134
+ - lib/opal/knockout/view_model.rb
135
+ - opal-knockout.gemspec
136
+ - spec/knockout/index.html.erb
137
+ - spec/spec_helper.rb
138
+ homepage: https://github.com/patorash/opal-knockout
139
+ licenses:
140
+ - MIT
141
+ metadata: {}
142
+ post_install_message:
143
+ rdoc_options: []
144
+ require_paths:
145
+ - lib
146
+ required_ruby_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ required_rubygems_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ requirements: []
157
+ rubyforge_project:
158
+ rubygems_version: 2.4.5.1
159
+ signing_key:
160
+ specification_version: 4
161
+ summary: Opal library for knockout.js
162
+ test_files:
163
+ - spec/knockout/index.html.erb
164
+ - spec/spec_helper.rb
165
+ has_rdoc: