receptive 0.1.0.alpha

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,87 @@
1
+ require 'receptive/incremental-dom-0.5.1'
2
+ require 'console'
3
+ require 'js'
4
+
5
+ module Receptive::IncrementalDOM
6
+ extend self
7
+ # Keep the var in the closure
8
+ `var native = #{JS.global.JS[:IncrementalDOM]}`
9
+
10
+ def patch_element(element, patch, data = nil)
11
+ `native`.JS.patch(element, patch.to_n, data.to_n)
12
+ end
13
+
14
+ # Add a tag
15
+ # @param tagname [String]
16
+ def tag(tagname, uid = nil, static_props = nil, dynamic_props = nil, &block)
17
+ if Hash === static_props
18
+ static_props = static_props.to_a.flatten
19
+ end
20
+
21
+ if Hash === dynamic_props
22
+ innerHTML = dynamic_props.delete(:innerHTML) if Hash === dynamic_props
23
+ dynamic_props = dynamic_props.to_a.flatten
24
+ # l innerHTML: innerHTML
25
+ end
26
+
27
+ dynamic_props ||= []
28
+ if block_given?
29
+ raise ArgumentError, 'cannot accept both a block and innerHTML' if innerHTML
30
+ `native`.JS.elementOpen(tagname, uid.to_n, static_props.to_n, *dynamic_props)
31
+ result = block.call
32
+ text result if String === result
33
+ `native`.JS.elementClose(tagname)
34
+ else
35
+ node = `native`.JS.elementVoid(tagname, uid.to_n, static_props.to_n, *dynamic_props)
36
+ node.JS[:innerHTML] = innerHTML
37
+ node
38
+ end
39
+ end
40
+
41
+ # Add a text node
42
+ def text(value, &formatter)
43
+ if block_given?
44
+ `native`.JS.text(value, formatter)
45
+ else
46
+ `native`.JS.text(value)
47
+ end
48
+ end
49
+
50
+ # @param element [DOM Node] doesn't accept jQuery elements
51
+ def update_element(element, data = nil, &block)
52
+ t0 = `performance.now()` if $DEBUG
53
+ patch_element(element, -> { block.call(self) }, data)
54
+ if $DEBUG
55
+ t1 = `performance.now()`
56
+ $console.log(
57
+ "%c render/incremental %c #{inspect} %c #{t1 - t0}ms ",
58
+ 'background-color:#eee;color:#444;border-radius:2px 0 0 2px',
59
+ 'background-color:#94E2C8;color:#193F32;border-radius:0 2px 2px 0',
60
+ 'background-color:none;border:none;font-family:monospace;',
61
+ data.to_n,
62
+ element
63
+ )
64
+ end
65
+ end
66
+
67
+ module DSL
68
+ HTML_TAGS = %w(a abbr address area article aside audio b base bdi bdo big blockquote body br
69
+ button canvas caption cite code col colgroup data datalist dd del details dfn
70
+ dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5
71
+ h6 head header hr html i iframe img input ins kbd keygen label legend li link
72
+ main map mark menu menuitem meta meter nav noscript object ol optgroup option
73
+ output p param picture pre progress q rp rt ruby s samp script section select
74
+ small source span strong style sub summary sup table tbody td textarea tfoot th
75
+ thead time title tr track u ul var video wbr)
76
+
77
+ HTML_TAGS.each do |tagname|
78
+ define_method tagname do |params, &block|
79
+ tag tagname, nil, nil, params, &block
80
+ end
81
+ end
82
+
83
+ def _p(*args)
84
+ Kernel.p(*args)
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,95 @@
1
+ module Receptive::View
2
+ def self.extenders
3
+ @extenders ||= []
4
+ end
5
+
6
+ def self.extended(base)
7
+ extenders << base
8
+ end
9
+
10
+ attr_accessor :selector
11
+
12
+ def setup
13
+ # noop, this is hook for extenders
14
+ end
15
+
16
+ def selector
17
+ @selector or raise('Please set the selector')
18
+ end
19
+
20
+ def persistent_events
21
+ @persistent_events ||= []
22
+ end
23
+
24
+ def setup_persistent_events
25
+ setup
26
+ persistent_events.each do |persistent_event|
27
+ element, event, selector, block = *persistent_event
28
+ selector ?
29
+ element.on(event, selector, &block) :
30
+ element.on(event, &block)
31
+ end
32
+ end
33
+
34
+ def on event, selector = '', &block
35
+ selector = combine_selectors([self.selector, selector])
36
+ persistent_events << [Document, event, selector, block]
37
+ end
38
+
39
+ def on_window(event, selector = nil, &block)
40
+ window = Window.element
41
+ on_document('page:change', selector) { window.on(event, &block) }
42
+ on_document('page:before-unload', selector) { window.off(event, &block) }
43
+ end
44
+
45
+ def on_document(event, selector = nil, &block)
46
+ persistent_events << [Document, event, nil, block_with_guard(block, selector)]
47
+ end
48
+
49
+ def block_with_guard(block, selector)
50
+ selector = combine_selectors([self.selector, selector])
51
+ block_with_guard = -> *args { block.call(*args) if Document.has? selector }
52
+ end
53
+
54
+ def find(selector = '')
55
+ Document.find(combine_selectors([self.selector, selector]))
56
+ end
57
+
58
+ # Support combining multiple selectors with commas
59
+ def combine_selectors(*selectors)
60
+ selectors = selectors.flatten.compact
61
+ splitted = selectors.map { |s| next if s.nil? or s.empty?; s.split(',') }.compact
62
+ return '' if splitted.size.zero?
63
+ return splitted.join(', ') if splitted.size == 1
64
+
65
+ # About Array#product:
66
+ #
67
+ # >> ['a,b', 'c,d'].map{|s| s.split(',')}.reduce(:product)
68
+ # => [["a", "c"], ["a", "d"], ["b", "c"], ["b", "d"]]
69
+ #
70
+ return splitted.reduce(:product).map {|s| s.join(' ')}.join(', ')
71
+ end
72
+
73
+ alias :element :find
74
+
75
+
76
+ # Rendering
77
+
78
+ def render
79
+ warn "#{name}#render not found, should be implemented!"
80
+ end
81
+
82
+ def render!
83
+ $console.log(
84
+ "%c render %c #{inspect} %c #{selector} ",
85
+ 'background-color:#eee;color:#444;border-radius:2px 0 0 2px',
86
+ 'background-color:#BFE99C;color:#30491B;border-radius:0 2px 2px 0',
87
+ 'background-color:none;border:none;font-family:monospace;',
88
+ self
89
+ ) if $DEBUG
90
+ `window`.JS.requestAnimationFrame(&method(:render))
91
+ nil
92
+ end
93
+
94
+ alias_method :on_event, :on_document
95
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'receptive/version'
4
+ require 'opal'
5
+
6
+ module Receptive
7
+ PATHS = ["#{__dir__}/../lib-opal".freeze]
8
+
9
+ def self.paths
10
+ PATHS
11
+ end
12
+ end
13
+
14
+ Receptive.paths.each { |path| Opal.append_path path }
@@ -0,0 +1,3 @@
1
+ module Receptive
2
+ VERSION = "0.1.0.alpha"
3
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path("../lib", __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require "receptive/version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "receptive"
9
+ spec.version = Receptive::VERSION
10
+ spec.authors = ["Elia Schito"]
11
+ spec.email = ["elia@schito.me"]
12
+
13
+ spec.summary = %q{The perfect toolkit to lighten up your existing HTML}
14
+ spec.homepage = "https://github.com/elia/receptive#readme"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_dependency "opal", [">= 0.10.5", "< 0.12"]
25
+ spec.add_dependency "opal-jquery", ["~> 0.4.2"]
26
+ spec.add_dependency "opal-minitest", "0.0.5"
27
+
28
+ spec.add_development_dependency "bundler", "~> 1.16"
29
+ spec.add_development_dependency "rake", "~> 10.0"
30
+ spec.add_development_dependency "minitest", "~> 5.0"
31
+ end
@@ -0,0 +1,12 @@
1
+ require "test_helper"
2
+
3
+ class ReceptiveTest < Minitest::Test
4
+ def test_silence_logs
5
+ $DEBUG = true
6
+ debug_value_inside_block = nil
7
+ Receptive.silence_logs do
8
+ debug_value_inside_block = $DEBUG
9
+ end
10
+ assert_equal(false, debug_value_inside_block)
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ require "test_helper"
2
+
3
+ class ReceptiveViewTest < Minitest::Test
4
+ def test_combine_selectors
5
+ subject = Object.new.tap {|o| o.extend Receptive::View}
6
+
7
+ assert_equal('' , subject.combine_selectors(nil ))
8
+ assert_equal('a' , subject.combine_selectors('a' ))
9
+ assert_equal('a b' , subject.combine_selectors('a', 'b' ))
10
+ assert_equal('a c, b c' , subject.combine_selectors('a,b', 'c' ))
11
+ assert_equal('a c, a d, b c, b d' , subject.combine_selectors('a,b', 'c,d'))
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
2
+ require "receptive"
3
+
4
+ # require "minitest/autorun"
5
+ require 'opal/platform'
6
+ require 'minitest'
7
+ `if (typeof(window) === 'undefined') window = Opal.global;` # for nodejs
8
+ at_exit { Minitest.run ARGV; exit `Opal.global.OPAL_TEST_EXIT_STATUS` || 1 }
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: receptive
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.alpha
5
+ platform: ruby
6
+ authors:
7
+ - Elia Schito
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-02-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: opal
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.10.5
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '0.12'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 0.10.5
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '0.12'
33
+ - !ruby/object:Gem::Dependency
34
+ name: opal-jquery
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 0.4.2
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 0.4.2
47
+ - !ruby/object:Gem::Dependency
48
+ name: opal-minitest
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - '='
52
+ - !ruby/object:Gem::Version
53
+ version: 0.0.5
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - '='
59
+ - !ruby/object:Gem::Version
60
+ version: 0.0.5
61
+ - !ruby/object:Gem::Dependency
62
+ name: bundler
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '1.16'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '1.16'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rake
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '10.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '10.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: minitest
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '5.0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '5.0'
103
+ description:
104
+ email:
105
+ - elia@schito.me
106
+ executables: []
107
+ extensions: []
108
+ extra_rdoc_files: []
109
+ files:
110
+ - ".gitignore"
111
+ - ".travis.yml"
112
+ - Gemfile
113
+ - Gemfile.lock
114
+ - HANDBOOK.md
115
+ - LICENSE.txt
116
+ - README.md
117
+ - Rakefile
118
+ - bin/console
119
+ - bin/setup
120
+ - lib-opal/receptive.js.rb
121
+ - lib-opal/receptive/app.rb
122
+ - lib-opal/receptive/incremental-dom-0.5.1.js
123
+ - lib-opal/receptive/incremental_dom.js.rb
124
+ - lib-opal/receptive/view.rb
125
+ - lib/receptive.rb
126
+ - lib/receptive/version.rb
127
+ - receptive.gemspec
128
+ - test-opal/receptive_test.rb
129
+ - test-opal/receptive_view_test.rb
130
+ - test-opal/test_helper.rb
131
+ homepage: https://github.com/elia/receptive#readme
132
+ licenses:
133
+ - MIT
134
+ metadata: {}
135
+ post_install_message:
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - ">"
147
+ - !ruby/object:Gem::Version
148
+ version: 1.3.1
149
+ requirements: []
150
+ rubyforge_project:
151
+ rubygems_version: 2.7.4
152
+ signing_key:
153
+ specification_version: 4
154
+ summary: The perfect toolkit to lighten up your existing HTML
155
+ test_files: []