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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bef64d09d4fdc73c08a83c9b3014a8a28685d0d261fb6af08ca2d68242792579
4
- data.tar.gz: 66f34cb59d7423d8d84abca97e9d7425cd7fc344865e4a8eb170345116c7c4a1
3
+ metadata.gz: 6eb86fb33f7053193df400df56389ceaecad3b8857b7e110da57353682f9d7a3
4
+ data.tar.gz: f713f308fbb0cf9fbdd5f965465e8d875571fc07a2b126e38403236124b047f2
5
5
  SHA512:
6
- metadata.gz: 59b52a1d608eccbc4dcb16a7f3dc7d9c3190c23c32a1f9b9b465efae5fcb47b5d53b89214597bb3e1b938eb4eeeb046c052dbfe8ae25c71a7ba9af46f5902bad
7
- data.tar.gz: 4c1edfc03d78c96b61329bfb854177c6965e7536599c9e0367a180b720fc3d3f34ddb6a01c7245f97d601d668b1a03fddf82bd7012f4a3531217fcbe742f8812
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.4 (Beta)
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.4'
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 66.66% 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.
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.4
1
+ 0.6.5
@@ -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.4 ruby lib
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.4"
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-07"
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, evaluated_property_value) || 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
- converted_view_property_value = element_binding_write_translator&.call(view_property_value, model_binding.evaluate_property) || view_property_value
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
- else
889
- old_value
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
- else
913
- old_value
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
- else
936
- old_value
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, :month_string, :week_string
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, :month_string, computed_by: :date_time]
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 <=> [@time_presenter, :week_string, computed_by: :date_time]
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
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-07 00:00:00.000000000 Z
11
+ date: 2025-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer