porous 0.1.0 → 0.1.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +17 -1
- data/CHANGELOG.md +4 -0
- data/README.md +2 -2
- data/Rakefile +3 -3
- data/exe/porous +2 -0
- data/lib/porous/cli/build.rb +2 -0
- data/lib/porous/cli/new.rb +2 -0
- data/lib/porous/cli/server.rb +3 -3
- data/lib/porous/cli/template/pages/home.rb +8 -4
- data/lib/porous/cli.rb +2 -0
- data/lib/porous/component/class_methods.rb +2 -0
- data/lib/porous/component/render.rb +3 -2
- data/lib/porous/component/virtual.rb +2 -0
- data/lib/porous/component.rb +2 -1
- data/lib/porous/injection.rb +8 -6
- data/lib/porous/page.rb +3 -1
- data/lib/porous/router.rb +20 -11
- data/lib/porous/routes.rb +12 -4
- data/lib/porous/server.rb +52 -27
- data/lib/porous/version.rb +1 -1
- data/lib/porous.rb +3 -1
- data/lib/virtual_dom/dom.rb +12 -8
- data/lib/virtual_dom/virtual_node.rb +3 -1
- data/opal/porous/browser.rb +2 -0
- data/opal/porous/component/class_methods.rb +2 -0
- data/opal/porous/component/render.rb +26 -23
- data/opal/porous/component/virtual.rb +2 -0
- data/opal/porous/component.rb +2 -0
- data/opal/porous/injection.rb +8 -8
- data/opal/porous.rb +2 -0
- metadata +12 -67
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b55c1eaf688f84af5c848e212ab0f5686ca6d6f270a0ef68d35846824af0d716
|
4
|
+
data.tar.gz: 4ca350f60c41896911dba97cd62ec05437ede55ae11d0a6c1fd0e3a68a09281e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a434473bf2ee80768ed88e729ecec2287af5a2596521e4fdb1857e82cff861eaeeba84ac9be5b6afba41340f6de543a7c57e1382e4a6d6e19e85960f0e6ea0c6
|
7
|
+
data.tar.gz: 5ddf2319739891025fac39dfc34d50a379f2403139f6171d95d2488eabf621b22dacad1266c9151af35242dff02210aef15ccc350d3b9f1c782c0c2d585f7a8b
|
data/.rubocop.yml
CHANGED
@@ -1,13 +1,29 @@
|
|
1
1
|
AllCops:
|
2
2
|
TargetRubyVersion: 3.0
|
3
|
+
NewCops: enable
|
3
4
|
|
4
5
|
Style/StringLiterals:
|
5
6
|
Enabled: true
|
6
|
-
EnforcedStyle:
|
7
|
+
EnforcedStyle: single_quotes
|
7
8
|
|
8
9
|
Style/StringLiteralsInInterpolation:
|
9
10
|
Enabled: true
|
10
11
|
EnforcedStyle: double_quotes
|
11
12
|
|
13
|
+
Style/Documentation:
|
14
|
+
Enabled: false
|
15
|
+
|
12
16
|
Layout/LineLength:
|
13
17
|
Max: 120
|
18
|
+
|
19
|
+
Metrics/BlockLength:
|
20
|
+
AllowedMethods:
|
21
|
+
- render
|
22
|
+
Metrics/MethodLength:
|
23
|
+
Max: 15
|
24
|
+
AllowedMethods:
|
25
|
+
- render
|
26
|
+
|
27
|
+
require:
|
28
|
+
- rubocop-rake
|
29
|
+
- rubocop-rspec
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -40,7 +40,7 @@ To start a new Porous project simply `gem install porous` using whichever Ruby e
|
|
40
40
|
|
41
41
|
$ porous server
|
42
42
|
|
43
|
-
By default Porous will run at `loclahost:9292`. Now you can edit `pages/home.rb` or add more pages.
|
43
|
+
By default Porous will run at `loclahost:9292`. Now you can edit `pages/home.rb` or add more pages. Files you modify will be reloaded so you can simply refresh the page in your browser. Hot-reloading will be coming later once WebSockets support is implemented.
|
44
44
|
|
45
45
|
### Running examples
|
46
46
|
|
@@ -66,4 +66,4 @@ Everyone interacting in the Porous project's codebases, issue trackers, chat roo
|
|
66
66
|
|
67
67
|
## Acknowledgements
|
68
68
|
|
69
|
-
|
69
|
+
I'd like to thank Michał Kalbarczyk ([fazibear](https://github.com/fazibear)) for his work done on [Inesita](https://github.com/inesita-rb/inesita) and his [VirtualDOM wrapper](https://github.com/fazibear/opal-virtual-dom) which served as the starting point for my implementation of Porous.
|
data/Rakefile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rspec/core/rake_task'
|
5
5
|
|
6
6
|
RSpec::Core::RakeTask.new(:spec)
|
7
7
|
|
8
|
-
require
|
8
|
+
require 'rubocop/rake_task'
|
9
9
|
|
10
10
|
RuboCop::RakeTask.new
|
11
11
|
|
data/exe/porous
CHANGED
data/lib/porous/cli/build.rb
CHANGED
data/lib/porous/cli/new.rb
CHANGED
data/lib/porous/cli/server.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Porous
|
2
4
|
class CLI < Thor
|
3
5
|
check_unknown_options!
|
@@ -18,9 +20,7 @@ module Porous
|
|
18
20
|
desc: 'The host address Porous will bind to'
|
19
21
|
|
20
22
|
def server
|
21
|
-
Rackup::Server.start environment: 'development', builder:
|
22
|
-
run Porous::Server.new
|
23
|
-
BUILDER
|
23
|
+
Rackup::Server.start environment: 'development', builder: 'run Porous::Server.new'
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -1,15 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Home
|
2
4
|
include Porous::Page
|
3
5
|
include Porous::Component
|
4
6
|
|
5
7
|
def route = '/'
|
6
8
|
|
9
|
+
# rubocop:disable Metrics, Layout/LineLength
|
7
10
|
def render
|
8
11
|
div class: 'container p-8 mx-auto lg:h-full xl:px-0 flex flex-wrap' do
|
9
12
|
div class: 'flex items-center w-full lg:w-1/2' do
|
10
13
|
div class: 'max-w-2xl mb-8' do
|
11
14
|
h1 class: 'text-4xl font-bold leading-snug tracking-tight text-gray-800 lg:text-4xl lg:leading-tight xl:text-6xl xl:leading-tight dark:text-white' do
|
12
|
-
span class:
|
15
|
+
span class: 'bg-gradient-to-br from-pink-500 to-violet-500 bg-clip-text text-transparent box-decoration-clone' do
|
13
16
|
text 'Welcome to Porous!'
|
14
17
|
end
|
15
18
|
end
|
@@ -19,10 +22,10 @@ class Home
|
|
19
22
|
|
20
23
|
div class: 'flex flex-col items-start space-y-3 sm:space-x-4 sm:space-y-0 sm:items-center sm:flex-row' do
|
21
24
|
a href: 'https://github.com/exastencil/porous', target: '_blank', rel: 'noopener',
|
22
|
-
class:
|
25
|
+
class: 'group relative inline-flex h-12 items-center justify-center overflow-hidden rounded-md bg-indigo-600 px-6 font-medium text-neutral-200 transition hover:scale-110' do
|
23
26
|
span 'Get Started'
|
24
|
-
div class:
|
25
|
-
div class:
|
27
|
+
div class: 'absolute inset-0 flex h-full w-full justify-center [transform:skew(-12deg)_translateX(-100%)] group-hover:duration-1000 group-hover:[transform:skew(-12deg)_translateX(100%)]' do
|
28
|
+
div class: 'relative h-full w-8 bg-white/20'
|
26
29
|
end
|
27
30
|
end
|
28
31
|
a href: 'https://github.com/exastencil/porous', target: '_blank', rel: 'noopener',
|
@@ -45,4 +48,5 @@ class Home
|
|
45
48
|
end
|
46
49
|
end
|
47
50
|
end
|
51
|
+
# rubocop:enable Metrics, Layout/LineLength
|
48
52
|
end
|
data/lib/porous/cli.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Porous
|
2
4
|
module Component
|
3
5
|
module Render
|
@@ -5,8 +7,7 @@ module Porous
|
|
5
7
|
raise Error, "Implement #render in #{self.class} component"
|
6
8
|
end
|
7
9
|
|
8
|
-
def before_render
|
9
|
-
end
|
10
|
+
def before_render; end
|
10
11
|
|
11
12
|
def render_virtual_dom
|
12
13
|
before_render
|
data/lib/porous/component.rb
CHANGED
data/lib/porous/injection.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Porous
|
2
4
|
module Injection
|
3
5
|
def init; end
|
@@ -21,15 +23,15 @@ module Porous
|
|
21
23
|
def init_injections
|
22
24
|
@injections ||= {}
|
23
25
|
self.class.injections.each do |name, clazz|
|
24
|
-
|
25
|
-
@injections[name] = clazz
|
26
|
-
.new
|
27
|
-
.with_root_component(@root_component)
|
28
|
-
else
|
26
|
+
unless clazz.included_modules.include?(Porous::Injection)
|
29
27
|
raise Error, "Invalid #{clazz} class, should mixin Porous::Injection"
|
30
28
|
end
|
29
|
+
|
30
|
+
@injections[name] = clazz
|
31
|
+
.new
|
32
|
+
.with_root_component(@root_component)
|
31
33
|
end
|
32
|
-
@injections.
|
34
|
+
@injections.each_value do |instance|
|
33
35
|
instance.inject
|
34
36
|
instance.init
|
35
37
|
end
|
data/lib/porous/page.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Porous
|
2
4
|
module Page
|
3
5
|
# Define the route according to the Router::Routes rules
|
4
6
|
def route!
|
5
7
|
path = route
|
6
|
-
@
|
8
|
+
@route ||= Routes.new.tap do |routes|
|
7
9
|
routes.route path, to: self.class
|
8
10
|
end
|
9
11
|
end
|
data/lib/porous/router.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Porous
|
2
|
-
|
4
|
+
class Router
|
3
5
|
include Porous::Component
|
4
6
|
|
5
7
|
attr_reader :params
|
@@ -23,6 +25,10 @@ module Porous
|
|
23
25
|
parse_url_params
|
24
26
|
end
|
25
27
|
|
28
|
+
def routes
|
29
|
+
@routes.routes
|
30
|
+
end
|
31
|
+
|
26
32
|
def self.included(base)
|
27
33
|
base.extend(Porous::Component::ClassMethods)
|
28
34
|
end
|
@@ -34,7 +40,8 @@ module Porous
|
|
34
40
|
|
35
41
|
return @route = route
|
36
42
|
end
|
37
|
-
|
43
|
+
available_routes = @routes.routes.map { |r| " #{r[:path]} => #{r[:component]}" }.join
|
44
|
+
raise InvalidRouteError, "Unknown route for: #{path}\n\nAvailable routes:\n\n#{available_routes}"
|
38
45
|
end
|
39
46
|
|
40
47
|
def find_component(route)
|
@@ -50,9 +57,9 @@ module Porous
|
|
50
57
|
def call_on_enter_callback(route)
|
51
58
|
return unless route[:on_enter]
|
52
59
|
|
53
|
-
|
54
|
-
|
55
|
-
|
60
|
+
return unless route[:on_enter].respond_to?(:call)
|
61
|
+
|
62
|
+
route[:on_enter].call
|
56
63
|
end
|
57
64
|
|
58
65
|
def go_to(path)
|
@@ -66,14 +73,16 @@ module Porous
|
|
66
73
|
|
67
74
|
def parse_url_params
|
68
75
|
@params = component_url_params
|
69
|
-
query
|
76
|
+
return if query.empty?
|
77
|
+
|
78
|
+
query[1..].split('&').each do |param|
|
70
79
|
key, value = param.split('=')
|
71
80
|
@params[key] = value
|
72
|
-
end
|
81
|
+
end
|
73
82
|
end
|
74
83
|
|
75
84
|
def component_url_params
|
76
|
-
|
85
|
+
@route[:params].zip(path.match(@route[:regex])[1..]).to_h
|
77
86
|
end
|
78
87
|
|
79
88
|
def url_for(name, params = nil)
|
@@ -104,9 +113,9 @@ module Porous
|
|
104
113
|
|
105
114
|
def url_with_params(route, params)
|
106
115
|
path = route[:path]
|
107
|
-
params
|
108
|
-
path = path.gsub(":#{key}",
|
109
|
-
end
|
116
|
+
params&.each do |key, value|
|
117
|
+
path = path.gsub(":#{key}", value.to_s)
|
118
|
+
end
|
110
119
|
path
|
111
120
|
end
|
112
121
|
end
|
data/lib/porous/routes.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Porous
|
2
4
|
class Routes
|
3
5
|
attr_reader :routes
|
@@ -7,8 +9,9 @@ module Porous
|
|
7
9
|
@routes = []
|
8
10
|
end
|
9
11
|
|
12
|
+
# rubocop:disable Metrics/AbcSize
|
10
13
|
def route(*params, &block)
|
11
|
-
path = params.first.gsub(
|
14
|
+
path = params.first.gsub(%r{^/}, '')
|
12
15
|
path = @parent ? "#{@parent}/#{path}" : "/#{path}"
|
13
16
|
|
14
17
|
add_subroutes(path, &block) if block_given?
|
@@ -19,12 +22,15 @@ module Porous
|
|
19
22
|
add_route(params.last[:as], path, params.last[:to], params.last[:props], params.last[:on_enter])
|
20
23
|
end
|
21
24
|
end
|
25
|
+
# rubocop:enable Metrics/AbcSize
|
22
26
|
|
23
27
|
def validate_component(component)
|
24
28
|
raise Error, 'Component not exists' unless component
|
25
29
|
|
30
|
+
return if component.include?(Porous::Component)
|
31
|
+
|
26
32
|
raise Error,
|
27
|
-
"Invalid #{component} class, should mixin Porous::Component"
|
33
|
+
"Invalid #{component} class, should mixin Porous::Component"
|
28
34
|
end
|
29
35
|
|
30
36
|
def add_redirect(path, redirect_to)
|
@@ -51,6 +57,7 @@ module Porous
|
|
51
57
|
@routes += subroutes.routes
|
52
58
|
end
|
53
59
|
|
60
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
54
61
|
def build_params_and_regex(path)
|
55
62
|
regex = ['^']
|
56
63
|
params = []
|
@@ -62,10 +69,10 @@ module Porous
|
|
62
69
|
regex << '\/'
|
63
70
|
case part[0]
|
64
71
|
when ':'
|
65
|
-
params << part[1
|
72
|
+
params << part[1..]
|
66
73
|
regex << '([^\/]+)'
|
67
74
|
when '*'
|
68
|
-
params << part[1
|
75
|
+
params << part[1..]
|
69
76
|
regex << '(.*)'
|
70
77
|
break
|
71
78
|
else
|
@@ -78,6 +85,7 @@ module Porous
|
|
78
85
|
params: params
|
79
86
|
}
|
80
87
|
end
|
88
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
81
89
|
|
82
90
|
def combine(other)
|
83
91
|
@routes += other.routes
|
data/lib/porous/server.rb
CHANGED
@@ -1,41 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Porous
|
2
|
-
class
|
3
|
-
|
4
|
-
include Porous::Router
|
5
|
-
end
|
4
|
+
class Application
|
5
|
+
include Porous::Component
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
head do
|
13
|
-
title do
|
14
|
-
text props[:title]
|
15
|
-
end
|
16
|
-
meta charset: 'UTF-8'
|
17
|
-
meta name: 'viewport', content: 'width=device-width, initial-scale=1.0'
|
18
|
-
script src: 'https://cdn.tailwindcss.com'
|
7
|
+
def render
|
8
|
+
html do
|
9
|
+
head do
|
10
|
+
title do
|
11
|
+
text props[:title]
|
19
12
|
end
|
13
|
+
meta charset: 'UTF-8'
|
14
|
+
meta name: 'viewport', content: 'width=device-width, initial-scale=1.0'
|
15
|
+
script src: 'https://cdn.tailwindcss.com'
|
16
|
+
end
|
20
17
|
|
21
|
-
|
22
|
-
|
23
|
-
|
18
|
+
body class: 'bg-gray-50 dark:bg-gray-900' do
|
19
|
+
component Porous::Router, props: { path: props[:path], query: props[:query] }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Server
|
26
|
+
MONITORING = %w[components pages].freeze
|
27
|
+
|
28
|
+
def initialize(*_args)
|
29
|
+
@queue = Queue.new
|
30
|
+
start_live_reload
|
31
|
+
setup_rack_app
|
32
|
+
end
|
33
|
+
|
34
|
+
def start_live_reload
|
35
|
+
MONITORING.each { |path| FileUtils.mkdir_p path }
|
36
|
+
opts = {
|
37
|
+
only: /\.rb$/,
|
38
|
+
relative: true
|
39
|
+
}
|
40
|
+
@listener = Listen.to(*MONITORING, opts) do |modified, added, _removed|
|
41
|
+
(modified + added).each do |file|
|
42
|
+
load File.expand_path("#{Dir.pwd}/#{file}")
|
24
43
|
end
|
44
|
+
setup_rack_app
|
25
45
|
end
|
46
|
+
@listener.start
|
47
|
+
at_exit { @listener.stop }
|
26
48
|
end
|
27
49
|
|
28
|
-
def
|
50
|
+
def setup_rack_app
|
29
51
|
@rack = Rack::Builder.new do
|
30
52
|
use Rack::Static, urls: ['/static']
|
31
53
|
run do |env|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
54
|
+
# Build a router to check for a valid route
|
55
|
+
Porous::Router.new path: env['PATH_INFO'], query: env['QUERY_STRING']
|
56
|
+
[200, { 'content-type' => 'text/html' },
|
57
|
+
[Application.new(title: 'Porous Web', path: env['PATH_INFO'], query: env['QUERY_STRING']).to_s]]
|
58
|
+
rescue Porous::InvalidRouteError => e
|
59
|
+
[404, { 'content-type' => 'text/plain' },
|
60
|
+
["404 Page not found\n", e.message]]
|
61
|
+
rescue Porous::Error => e
|
62
|
+
[500, { 'content-type' => 'text/plain' },
|
63
|
+
["500 Internal Server Error\n", e.message]]
|
39
64
|
end
|
40
65
|
end
|
41
66
|
end
|
data/lib/porous/version.rb
CHANGED
data/lib/porous.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'opal'
|
4
4
|
require 'opal-browser'
|
5
|
-
Opal.append_path File.expand_path('
|
5
|
+
Opal.append_path File.expand_path('../opal', __dir__)
|
6
6
|
|
7
7
|
require 'opal-virtual-dom'
|
8
8
|
require 'listen'
|
@@ -27,4 +27,6 @@ end
|
|
27
27
|
require 'porous/server'
|
28
28
|
|
29
29
|
module Porous
|
30
|
+
class Error < StandardError; end
|
31
|
+
class InvalidRouteError < Error; end
|
30
32
|
end
|
data/lib/virtual_dom/dom.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module VirtualDOM
|
2
4
|
module DOM
|
3
|
-
HTML_TAGS = %w
|
5
|
+
HTML_TAGS = %w[a abbr address area article aside audio b base bdi bdo big blockquote body br
|
4
6
|
button canvas caption cite code col colgroup data datalist dd del details dfn
|
5
7
|
dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5
|
6
8
|
h6 head header hr html i iframe img input ins kbd keygen label legend li link
|
7
9
|
main map mark menu menuitem meta meter nav noscript object ol optgroup option
|
8
10
|
output p param picture pre progress q rp rt ruby s samp script section select
|
9
11
|
small source span strong style sub summary sup table tbody td textarea tfoot th
|
10
|
-
thead time title tr track u ul var video wbr
|
12
|
+
thead time title tr track u ul var video wbr].freeze
|
11
13
|
|
12
|
-
SVG_TAGS = %w
|
14
|
+
SVG_TAGS = %w[svg path].freeze
|
13
15
|
|
14
16
|
(HTML_TAGS + SVG_TAGS).each do |tag|
|
15
17
|
define_method tag do |params = {}, &block|
|
@@ -38,7 +40,8 @@ module VirtualDOM
|
|
38
40
|
self
|
39
41
|
end
|
40
42
|
|
41
|
-
|
43
|
+
# rubocop:disable Style/MissingRespondToMissing, Metrics/MethodLength, Metrics/AbcSize
|
44
|
+
def method_missing(klass, params = {}, &block)
|
42
45
|
return unless @__last_virtual_node__
|
43
46
|
return unless @__virtual_nodes__
|
44
47
|
|
@@ -51,28 +54,29 @@ module VirtualDOM
|
|
51
54
|
end
|
52
55
|
|
53
56
|
class_params = @__last_virtual_node__.params.delete(:className)
|
54
|
-
method_params = if
|
57
|
+
method_params = if klass.end_with?('!')
|
55
58
|
{ id: clazz[0..-2],
|
56
59
|
class: merge_string(class_params, params[:class]) }
|
57
60
|
else
|
58
|
-
{ class: merge_string(class_params, params[:class],
|
61
|
+
{ class: merge_string(class_params, params[:class], klass.gsub('_', '-').gsub('--', '_')) }
|
59
62
|
end
|
60
63
|
params = @__last_virtual_node__.params.merge(params).merge(method_params)
|
61
64
|
process_tag(@__last_virtual_node__.name, params, block, children)
|
62
65
|
end
|
66
|
+
# rubocop:enable Style/MissingRespondToMissing, Metrics/MethodLength, Metrics/AbcSize
|
63
67
|
|
64
68
|
def merge_string(*params)
|
65
69
|
arr = []
|
66
70
|
params.each do |string|
|
67
71
|
next unless string
|
68
72
|
|
69
|
-
arr << string.split
|
73
|
+
arr << string.split
|
70
74
|
end
|
71
75
|
arr.join(' ')
|
72
76
|
end
|
73
77
|
|
74
78
|
def process_params(params)
|
75
|
-
params.dup.
|
79
|
+
params.dup.each_key do |k|
|
76
80
|
case k
|
77
81
|
when 'for'
|
78
82
|
params['htmlFor'] = params.delete('for')
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module VirtualDOM
|
2
4
|
class VirtualNode
|
3
5
|
attr_reader :name, :params, :children
|
@@ -15,7 +17,7 @@ module VirtualDOM
|
|
15
17
|
def to_s_params
|
16
18
|
return unless @params.any?
|
17
19
|
|
18
|
-
|
20
|
+
" #{@params.map { |k, v| "#{k}=\"#{v}\"" }.join(" ")}"
|
19
21
|
end
|
20
22
|
|
21
23
|
def to_s_children
|
data/opal/porous/browser.rb
CHANGED
@@ -1,27 +1,30 @@
|
|
1
|
-
|
2
|
-
module Component
|
3
|
-
module Render
|
4
|
-
def render
|
5
|
-
raise Error, "Implement #render in #{self.class} component"
|
6
|
-
end
|
1
|
+
# frozen_string_literal: true
|
7
2
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
3
|
+
module Porous
|
4
|
+
module Component
|
5
|
+
module Render
|
6
|
+
def render
|
7
|
+
raise Error, "Implement #render in #{self.class} component"
|
8
|
+
end
|
15
9
|
|
16
|
-
|
10
|
+
def render_if_root
|
11
|
+
return unless @virtual_dom && @root_node
|
17
12
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
13
|
+
new_virtual_dom = render_virtual_dom
|
14
|
+
diff = VirtualDOM.diff @virtual_dom, new_virtual_dom
|
15
|
+
VirtualDOM.patch @root_node, diff
|
16
|
+
@virtual_dom = new_virtual_dom
|
17
|
+
end
|
18
|
+
|
19
|
+
def before_render; end
|
20
|
+
|
21
|
+
def render_virtual_dom
|
22
|
+
before_render
|
23
|
+
@cache_component_counter = 0
|
24
|
+
@__virtual_nodes__ = []
|
25
|
+
render
|
26
|
+
to_vnode
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
27
30
|
end
|
data/opal/porous/component.rb
CHANGED
data/opal/porous/injection.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Porous
|
2
4
|
module Injection
|
3
5
|
def init; end
|
@@ -20,16 +22,14 @@ module Porous
|
|
20
22
|
|
21
23
|
def init_injections
|
22
24
|
@injections ||= {}
|
23
|
-
self.class.injections.each do |name,
|
24
|
-
|
25
|
-
|
26
|
-
.new
|
27
|
-
.with_root_component(@root_component)
|
28
|
-
else
|
29
|
-
raise Error, "Invalid #{clazz} class, should mixin Porous::Injection"
|
25
|
+
self.class.injections.each do |name, klass|
|
26
|
+
unless klass.included_modules.include?(Porous::Injection)
|
27
|
+
raise Error, "Invalid #{klass} class, should mixin Porous::Injection"
|
30
28
|
end
|
29
|
+
|
30
|
+
@injections[name] = klass.new.with_root_component(@root_component)
|
31
31
|
end
|
32
|
-
@injections.
|
32
|
+
@injections.each_value do |instance|
|
33
33
|
instance.inject
|
34
34
|
instance.init
|
35
35
|
end
|
data/opal/porous.rb
CHANGED
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: porous
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Exa Stencil
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-02-
|
11
|
+
date: 2024-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: listen
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '3.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '3.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: opal-browser
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -53,89 +53,33 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 0.6.1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rackup
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '1
|
61
|
+
version: '2.1'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '1
|
68
|
+
version: '2.1'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: thor
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '3
|
75
|
+
version: '1.3'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '3
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rake
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '13.0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '13.0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: rspec
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - "~>"
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '3.2'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - "~>"
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '3.2'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: rubocop
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - "~>"
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '1.21'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - "~>"
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '1.21'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: solargraph
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - "~>"
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: 0.50.0
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - "~>"
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: 0.50.0
|
82
|
+
version: '1.3'
|
139
83
|
description: Highly opinionated web engine (not a framework!) that can be scripted
|
140
84
|
with Ruby.
|
141
85
|
email:
|
@@ -190,6 +134,7 @@ metadata:
|
|
190
134
|
homepage_uri: https://github.com/exastencil/porous
|
191
135
|
source_code_uri: https://github.com/exastencil/porous
|
192
136
|
changelog_uri: https://github.com/exastencil/porous/blob/main/CHANGELOG.md
|
137
|
+
rubygems_mfa_required: 'true'
|
193
138
|
post_install_message:
|
194
139
|
rdoc_options: []
|
195
140
|
require_paths:
|