glimmer-dsl-web 0.6.4 → 0.6.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +3 -3
- data/VERSION +1 -1
- data/glimmer-dsl-web.gemspec +3 -3
- data/lib/glimmer/data_binding/element_binding.rb +7 -1
- data/lib/glimmer/web/element_proxy.rb +50 -14
- data/lib/glimmer-dsl-web/samples/hello/hello_input_date_time.rb +9 -18
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6eb86fb33f7053193df400df56389ceaecad3b8857b7e110da57353682f9d7a3
|
4
|
+
data.tar.gz: f713f308fbb0cf9fbdd5f965465e8d875571fc07a2b126e38403236124b047f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98b0322be04f66756a304156880507c6f9cff290337d734709c3c6742693b0d0129e0e2a4c1af5e286ea41495e7c8064741d48f4e2e6d361049659d3619b0d3d
|
7
|
+
data.tar.gz: 05161d53f0d4a57a9b6c460ca6eef9a5a5e6606cfc21245ef77ca0c1720bac0116f619eccdf7b3e2a85018056e07a8e5525e23e05035edde0b84126b5ccb37c8
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.6.5
|
4
|
+
|
5
|
+
- Ensure clearing input datetime/date/time/month values sends `nil` to the data-bound model attribute (not `''`, which caused issues)
|
6
|
+
- Support data-binding input month vaue to a model attribute that has a datetime value
|
7
|
+
- Fix issue with clearing date/time from Hello, Input Date/Time! causing errors in the web browser console
|
8
|
+
|
3
9
|
## 0.6.4
|
4
10
|
|
5
11
|
- Support Rails 7.1 & 7.2 by upgrading to opal-rails 2.0.4
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Web 0.6.
|
1
|
+
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Web 0.6.5 (Beta)
|
2
2
|
## Ruby-in-the-Browser Web Frontend Framework
|
3
3
|
### The "Rails" of Frontend Frameworks!!!
|
4
4
|
#### Finally, Ruby Developer Productivity, Happiness, and Fun in the Frontend!!!
|
@@ -1404,7 +1404,7 @@ rails new glimmer_app_server
|
|
1404
1404
|
Add the following to `Gemfile`:
|
1405
1405
|
|
1406
1406
|
```
|
1407
|
-
gem 'glimmer-dsl-web', '~> 0.6.
|
1407
|
+
gem 'glimmer-dsl-web', '~> 0.6.5'
|
1408
1408
|
```
|
1409
1409
|
|
1410
1410
|
Run:
|
@@ -4558,7 +4558,7 @@ Glimmer DSL for Web is a Frontend library, meaning it replaces the JavaScript la
|
|
4558
4558
|
|
4559
4559
|
**How does Glimmer DSL for Web compare to Angular, React, Vue, Svelte, or other JS frameworks?**
|
4560
4560
|
|
4561
|
-
Without delving into details, Glimmer DSL for Web is meant to be a Ruby-based drop-in replacement for Angular, React, Vue, Svelte, and other JS frameworks. Glimmer Ruby code is transpiled to JavaScript, so it has JavaScript performance in general, which is not that far from that of Angular, React, or Vue. Glimmer DSL for Web has outperformed React by a factor of
|
4561
|
+
Without delving into details, Glimmer DSL for Web is meant to be a Ruby-based drop-in replacement for Angular, React, Vue, Svelte, and other JS frameworks. Glimmer Ruby code is transpiled to JavaScript, so it has JavaScript performance in general, which is not that far from that of Angular, React, or Vue. Glimmer DSL for Web has outperformed React by a factor of 33.33% in rendering 3000+ elements in a realistic app scenario that was benchmarked recently (in Oct 2024). Additionally, it enables writing both structure code and logic code in the same language (Ruby), greatly simplifying maintainability and improving productivity by eliminating multi-language dissonance and friction that drags down productivity as there is no need anymore to think in multiple languages unnecessarily, use XML based solutions (e.g. JSX), or use templating solutions (e.g. Mustache). Lastly, Glimmer DSL for Web supports familiar Software Engineering architectural patterns like Model-View-Controller and Model-View-Presenter, enabling Software Engineers to write the lightest and simplest code possible for building Web frontends in Ruby, with the best separation of concerns. Software Engineers can finally become happy Ruby developers by writing Ruby code in the Frontend too now in addition to the Backend.
|
4562
4562
|
|
4563
4563
|
**How do I have a Glimmer Web Component re-render in a similar way to how React components re-render?**
|
4564
4564
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.5
|
data/glimmer-dsl-web.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: glimmer-dsl-web 0.6.
|
5
|
+
# stub: glimmer-dsl-web 0.6.5 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "glimmer-dsl-web".freeze
|
9
|
-
s.version = "0.6.
|
9
|
+
s.version = "0.6.5"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["Andy Maleh".freeze]
|
14
|
-
s.date = "2025-01-
|
14
|
+
s.date = "2025-01-20"
|
15
15
|
s.description = "Glimmer DSL for Web (Ruby in the Browser Web Frontend Framework) enables building Web Frontends using Ruby in the Browser, as per Matz's recommendation in his RubyConf 2022 keynote speech to replace JavaScript with Ruby. It aims at providing the simplest, most intuitive, most straight-forward, and most productive frontend framework in existence. The framework follows the Ruby way (with DSLs and TIMTOWTDI) and the Rails way (Convention over Configuration) in building Isomorphic Ruby on Rails Applications. It provides a Ruby HTML DSL, which uniquely enables writing both structure code and logic code in one language. It supports both Unidirectional (One-Way) Data-Binding (using <=) and Bidirectional (Two-Way) Data-Binding (using <=>). Dynamic rendering (and re-rendering) of HTML content is also supported via Content Data-Binding. Modular design is supported with Glimmer Web Components, Component Slots, and Component Custom Event Listeners. And, a Ruby CSS DSL is supported with the included Glimmer DSL for CSS. Many samples are demonstrated in the Rails sample app (there is a very minimal Standalone [No Rails] sample app too). You can finally live in pure Rubyland on the Web in both the frontend and backend with Glimmer DSL for Web! This gem relies on Opal Ruby.".freeze
|
16
16
|
s.email = "andy.am@gmail.com".freeze
|
17
17
|
s.extra_rdoc_files = [
|
@@ -28,7 +28,13 @@ module Glimmer
|
|
28
28
|
|
29
29
|
def call(value)
|
30
30
|
evaluated_property_value = evaluate_property
|
31
|
-
converted_value = @translator&.call(value,
|
31
|
+
converted_value = @translator&.call(value, @old_value)
|
32
|
+
is_date_time = ['date', 'time', 'datetime-local', 'month'].include?(element.options['type'])
|
33
|
+
if !is_date_time
|
34
|
+
converted_value ||= value
|
35
|
+
end
|
36
|
+
|
37
|
+
@old_value = value
|
32
38
|
if converted_value != evaluated_property_value
|
33
39
|
if @sub_property
|
34
40
|
if @property.to_s == 'class_name'
|
@@ -137,12 +137,14 @@ module Glimmer
|
|
137
137
|
'inner_html' => 'innerHTML',
|
138
138
|
'outer_html' => 'outerHTML',
|
139
139
|
}
|
140
|
-
FORMAT_DATETIME = '%Y-%m-%dT%H:%M'
|
141
|
-
FORMAT_DATE = '%Y-%m-%d'
|
142
|
-
FORMAT_TIME = '%H:%M'
|
140
|
+
FORMAT_DATETIME = '%Y-%m-%dT%H:%M' # TODO ensure using when setting value on date/time fields without data-binding
|
141
|
+
FORMAT_DATE = '%Y-%m-%d' # TODO ensure using when setting value on date/time fields without data-binding
|
142
|
+
FORMAT_TIME = '%H:%M' # TODO ensure using when setting value on date/time fields without data-binding
|
143
|
+
FORMAT_MONTH = '%Y-%m' # TODO ensure using when setting value on date/time fields without data-binding
|
143
144
|
REGEX_FORMAT_DATETIME = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/
|
144
145
|
REGEX_FORMAT_DATE = /^\d{4}-\d{2}-\d{2}$/
|
145
146
|
REGEX_FORMAT_TIME = /^\d{2}:\d{2}$/
|
147
|
+
REGEX_FORMAT_MONTH = /^\d{4}-\d{2}$/
|
146
148
|
REGEX_STYLE_SUB_PROPERTY = /^(style)_(.*)$/
|
147
149
|
REGEX_CLASS_NAME_SUB_PROPERTY = /^(class_name)_(.*)$/
|
148
150
|
|
@@ -671,7 +673,11 @@ module Glimmer
|
|
671
673
|
data_binding_read_listener = lambda do |event|
|
672
674
|
view_property_value = send(property)
|
673
675
|
element_binding_write_translator = value_converters_for_input_type(type)&.[](:view_to_model)
|
674
|
-
|
676
|
+
is_date_time = ['date', 'time', 'datetime-local', 'month'].include?(options['type'])
|
677
|
+
converted_view_property_value = element_binding_write_translator&.call(view_property_value, model_binding.evaluate_property)
|
678
|
+
if !is_date_time
|
679
|
+
converted_view_property_value ||= view_property_value
|
680
|
+
end
|
675
681
|
model_binding.call(converted_view_property_value)
|
676
682
|
end
|
677
683
|
handle_observation_request(listener_keyword, data_binding_read_listener)
|
@@ -885,8 +891,10 @@ module Glimmer
|
|
885
891
|
value.strftime(FORMAT_DATETIME)
|
886
892
|
elsif value.is_a?(String) && valid_js_date_string?(value)
|
887
893
|
value
|
888
|
-
|
889
|
-
|
894
|
+
elsif value.to_s.empty?
|
895
|
+
''
|
896
|
+
else # keep old value if a bad model attribute value was set
|
897
|
+
old_value&.strftime(FORMAT_DATETIME)
|
890
898
|
end
|
891
899
|
},
|
892
900
|
view_to_model: -> (value, old_value) {
|
@@ -909,8 +917,10 @@ module Glimmer
|
|
909
917
|
value.strftime(FORMAT_DATE)
|
910
918
|
elsif value.is_a?(String) && valid_js_date_string?(value)
|
911
919
|
value
|
912
|
-
|
913
|
-
|
920
|
+
elsif value.to_s.empty?
|
921
|
+
''
|
922
|
+
else # keep old value if a bad model attribute value was set
|
923
|
+
old_value&.strftime(FORMAT_DATE)
|
914
924
|
end
|
915
925
|
},
|
916
926
|
view_to_model: -> (value, old_value) {
|
@@ -918,7 +928,7 @@ module Glimmer
|
|
918
928
|
nil
|
919
929
|
else
|
920
930
|
year, month, day = value.split('-')
|
921
|
-
if old_value
|
931
|
+
if !old_value.to_s.empty?
|
922
932
|
Time.new(year, month, day, old_value.hour, old_value.min)
|
923
933
|
else
|
924
934
|
Time.new(year, month, day)
|
@@ -932,8 +942,10 @@ module Glimmer
|
|
932
942
|
value.strftime(FORMAT_TIME)
|
933
943
|
elsif value.is_a?(String) && valid_js_date_string?(value)
|
934
944
|
value
|
935
|
-
|
936
|
-
|
945
|
+
elsif value.to_s.empty?
|
946
|
+
''
|
947
|
+
else # keep old value if a bad model attribute value was set
|
948
|
+
old_value&.strftime(FORMAT_TIME)
|
937
949
|
end
|
938
950
|
},
|
939
951
|
view_to_model: -> (value, old_value) {
|
@@ -941,7 +953,7 @@ module Glimmer
|
|
941
953
|
nil
|
942
954
|
else
|
943
955
|
hour, minute = value.split(':')
|
944
|
-
if old_value
|
956
|
+
if !old_value.to_s.empty?
|
945
957
|
Time.new(old_value.year, old_value.month, old_value.day, hour, minute)
|
946
958
|
else
|
947
959
|
now = Time.now
|
@@ -950,6 +962,31 @@ module Glimmer
|
|
950
962
|
end
|
951
963
|
},
|
952
964
|
},
|
965
|
+
'month' => {
|
966
|
+
model_to_view: -> (value, old_value) {
|
967
|
+
if value.respond_to?(:strftime)
|
968
|
+
value.strftime(FORMAT_MONTH)
|
969
|
+
elsif value.is_a?(String) && valid_js_date_string?(value)
|
970
|
+
value
|
971
|
+
elsif value.to_s.empty?
|
972
|
+
''
|
973
|
+
else # keep old value if a bad model attribute value was set
|
974
|
+
old_value&.strftime(FORMAT_MONTH)
|
975
|
+
end
|
976
|
+
},
|
977
|
+
view_to_model: -> (value, old_value) {
|
978
|
+
if value.to_s.empty?
|
979
|
+
nil
|
980
|
+
else
|
981
|
+
year, month = value.split('-')
|
982
|
+
if !old_value.to_s.empty?
|
983
|
+
Time.new(year, month, old_value.day, old_value.hour, old_value.min)
|
984
|
+
else
|
985
|
+
Time.new(year, month)
|
986
|
+
end
|
987
|
+
end
|
988
|
+
},
|
989
|
+
},
|
953
990
|
}
|
954
991
|
end
|
955
992
|
|
@@ -965,7 +1002,7 @@ module Glimmer
|
|
965
1002
|
end
|
966
1003
|
|
967
1004
|
def valid_js_date_string?(string)
|
968
|
-
[REGEX_FORMAT_DATETIME, REGEX_FORMAT_DATE, REGEX_FORMAT_TIME].any? do |format|
|
1005
|
+
[REGEX_FORMAT_DATETIME, REGEX_FORMAT_DATE, REGEX_FORMAT_TIME, REGEX_FORMAT_MONTH].any? do |format|
|
969
1006
|
string.match(format)
|
970
1007
|
end
|
971
1008
|
end
|
@@ -993,7 +1030,6 @@ module Glimmer
|
|
993
1030
|
style_value.to_s
|
994
1031
|
end
|
995
1032
|
end
|
996
|
-
|
997
1033
|
end
|
998
1034
|
end
|
999
1035
|
end
|
@@ -22,23 +22,12 @@
|
|
22
22
|
require 'glimmer-dsl-web'
|
23
23
|
|
24
24
|
class TimePresenter
|
25
|
-
attr_accessor :date_time, :
|
25
|
+
attr_accessor :date_time, :week_string
|
26
26
|
|
27
27
|
def initialize
|
28
28
|
@date_time = Time.now
|
29
29
|
end
|
30
30
|
|
31
|
-
def month_string
|
32
|
-
@date_time&.strftime('%Y-%m')
|
33
|
-
end
|
34
|
-
|
35
|
-
def month_string=(value)
|
36
|
-
if value.match(/^\d{4}-\d{2}$/)
|
37
|
-
year, month = value.split('-')
|
38
|
-
self.date_time = Time.new(year, month, date_time.day, date_time.hour, date_time.min)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
31
|
def week_string
|
43
32
|
return nil if @date_time.nil?
|
44
33
|
year = @date_time.year
|
@@ -56,6 +45,8 @@ class TimePresenter
|
|
56
45
|
date_parts = date_time_parts.first.split('-')
|
57
46
|
time_parts = date_time_parts.last.split(':')
|
58
47
|
self.date_time = Time.new(*date_parts, *time_parts)
|
48
|
+
elsif value.strip.empty?
|
49
|
+
self.date_time = nil
|
59
50
|
end
|
60
51
|
end
|
61
52
|
end
|
@@ -78,22 +69,22 @@ Document.ready? do
|
|
78
69
|
input(id: 'date-field', type: 'date') {
|
79
70
|
value <=> [@time_presenter, :date_time]
|
80
71
|
}
|
81
|
-
|
72
|
+
|
82
73
|
label('Time: ', for: 'time-field')
|
83
74
|
input(id: 'time-field', type: 'time') {
|
84
75
|
value <=> [@time_presenter, :date_time]
|
85
76
|
}
|
86
|
-
|
77
|
+
|
87
78
|
label('Month: ', for: 'month-field')
|
88
79
|
input(id: 'month-field', type: 'month') {
|
89
|
-
value <=> [@time_presenter, :
|
80
|
+
value <=> [@time_presenter, :date_time]
|
90
81
|
}
|
91
|
-
|
82
|
+
|
92
83
|
label('Week: ', for: 'week-field')
|
93
84
|
input(id: 'week-field', type: 'week', disabled: true) {
|
94
|
-
value
|
85
|
+
value <= [@time_presenter, :week_string, computed_by: :date_time]
|
95
86
|
}
|
96
|
-
|
87
|
+
|
97
88
|
label('Time String: ', for: 'time-string-field')
|
98
89
|
input(id: 'time-string-field', type: 'text') {
|
99
90
|
value <=> [@time_presenter, :date_time_string, computed_by: :date_time]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-dsl-web
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Maleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-01-
|
11
|
+
date: 2025-01-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glimmer
|