glimmer-dsl-web 0.2.2 → 0.2.4

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: 528b824876642a7d3cabb52d76ba8a93f55273443f0a4a25a308f14d80460bc4
4
- data.tar.gz: db5ba4f41d4f863074bd7d5e291b9b753995fb056612f763945ea4ad10ed2c7d
3
+ metadata.gz: 212cee9f2c87b145cca85b47395f541a749d0a472560a946c1f3b0061ec7b801
4
+ data.tar.gz: f7cccb64081e75018c6e043e021b071d70c7b2696057a32e25b191fb2c3dd4f6
5
5
  SHA512:
6
- metadata.gz: 820828cc1d4f45fbc23df7e1296f71e24959fe811e5b380470cbc8126484ffe9bef70351eb4534777e7398f1bcd30363e30172ebe33b1828871318603fe5a906
7
- data.tar.gz: 52a96a0c75fc7cc57b8e6938784f75079f3b5caf3d4b5a49801604b8061aec73518a23576a7ab6346937f8d4899c70b0b6efa33faf9ae1d35c75cbded956101a
6
+ metadata.gz: e590b30b6f3d54f859e168bd7220cfa51e8d3f2354836fb851ab20c21114518ddd2a502a74a262b704148561e64b65a07cbd2ed61593914a274fa7542da8e1c9
7
+ data.tar.gz: 1a334ce05e730c2eef25005d5a1a9d16683b639fac910e83ba0ceff88c380230df884486f994140bce11a68e10210ff1a28266604560ecaa134859b621402cf2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.2.4
4
+
5
+ - Enhance `Kernel#puts` & `Kernel#p` to enable printing any native JS object with `console.log` (without having to manually wrap with `Native`)
6
+ - Support Content Data-Binding from inside a `Glimmer::Web::Component`
7
+
8
+ ## 0.2.3
9
+
10
+ - Ensure that setting `element.class_name=classnameval` does not override its Glimmer built-in CSS classes
11
+ - Alias `Kernel#p` as `Kernel#pi` (puts inspect) to allow using `pi` in place of `p` for printing inspected objects given that `p` is used up by the HTML DSL.
12
+ - Remove `element` from dynamic part of Glimmer DSL to allow it to fail faster if an invalid HTML element name was used
13
+ - Fix use of `span` keyword under `p`, fixing Hello, Paragraph! sample.
14
+
3
15
  ## 0.2.2
4
16
 
5
17
  - Fix bug in content data-binding that was caused by recent performance optimizations (+ fix Hello, Content Data-Binding! sample)
data/README.md CHANGED
@@ -1,13 +1,15 @@
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.2.2 (Beta)
2
- ## Ruby in the Browser Web GUI Frontend Library
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.2.4 (Beta)
2
+ ## Ruby in the Browser Web Frontend Framework
3
3
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-web.svg)](http://badge.fury.io/rb/glimmer-dsl-web)
4
4
  [![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
5
5
 
6
- [Glimmer](https://github.com/AndyObtiva/glimmer) DSL for Web enables building Web GUI frontends using [Ruby in the Browser](https://www.youtube.com/watch?v=4AdcfbI6A4c), as per [Matz's recommendation in his RubyConf 2022 keynote speech to replace JavaScript with Ruby](https://youtu.be/knutsgHTrfQ?t=789). It aims at providing the simplest, most intuitive, most straight-forward, and most productive frontend library in existence. The library follows the Ruby way (with [DSLs](https://martinfowler.com/books/dsl.html) and [TIMTOWTDI](https://en.wiktionary.org/wiki/TMTOWTDI#English)) and the Rails way ([Convention over Configuration](https://rubyonrails.org/doctrine)) while supporting both Unidirectional (One-Way) [Data-Binding](#hello-data-binding) (using `<=`) and Bidirectional (Two-Way) [Data-Binding](#hello-data-binding) (using `<=>`). Dynamic rendering (and re-rendering) of HTML content is also supported via [Content Data-Binding](#hello-content-data-binding). And, modular design is supported with [Glimmer Web Components](#hello-component). You can finally live in pure Rubyland on the Web in both the frontend and backend with [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web)!
6
+ **(Based on Original [Glimmer](https://github.com/AndyObtiva/glimmer) Library Handling World’s Ruby GUI Needs Since 2007. Beware of Imitators!)**
7
+
8
+ [Glimmer](https://github.com/AndyObtiva/glimmer) DSL for Web enables building Web Frontends using [Ruby in the Browser](https://www.youtube.com/watch?v=4AdcfbI6A4c), as per [Matz's recommendation in his RubyConf 2022 keynote speech to replace JavaScript with Ruby](https://youtu.be/knutsgHTrfQ?t=789). 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](https://martinfowler.com/books/dsl.html) and [TIMTOWTDI](https://en.wiktionary.org/wiki/TMTOWTDI#English)) and the Rails way ([Convention over Configuration](https://rubyonrails.org/doctrine)) in building Isomorphic Ruby on Rails Applications. It provides a Ruby [HTML DSL](#usage), which uniquely enables writing both structure code and logic code in one language. It supports both Unidirectional (One-Way) [Data-Binding](#hello-data-binding) (using `<=`) and Bidirectional (Two-Way) [Data-Binding](#hello-data-binding) (using `<=>`). Dynamic rendering (and re-rendering) of HTML content is also supported via [Content Data-Binding](#hello-content-data-binding). And, modular design is supported with [Glimmer Web Components](#hello-component). Many [samples](#samples) are demonstrated in the [Rails sample app](https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app) (there is a very minimal [Standalone [No Rails] sample app](https://github.com/Largo/glimmer-dsl-web-standalone-demo) too). You can finally live in pure Rubyland on the Web in both the frontend and backend with [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web)!
7
9
 
8
10
  **Hello, World! Sample**
9
11
 
10
- Glimmer GUI code:
12
+ Glimmer HTML DSL Ruby code in the frontend:
11
13
 
12
14
  ```ruby
13
15
  require 'glimmer-dsl-web'
@@ -31,11 +33,13 @@ That produces the following under `<body></body>`:
31
33
 
32
34
  ![setup is working](/images/glimmer-dsl-web-setup-example-working.png)
33
35
 
36
+ You can also mount the `div` elsewhere by passing the `parent: parent_css_selector` option (e.g. `div(parent: 'div#app-container') { 'Hello, World!' }`).
37
+
34
38
  **Hello, Button!**
35
39
 
36
- Event listeners can be setup on any element using the same event names used in HTML (e.g. `onclick`) while passing in a standard Ruby block to handle behavior. `$$` gives access to `window` to invoke functions like `alert`.
40
+ Event listeners can be setup on any element using the same event names used in HTML (e.g. `onclick`) while passing in a standard Ruby block to handle behavior. `$$` gives access to JS global scope from Ruby to invoke functions like `alert`.
37
41
 
38
- Glimmer GUI code:
42
+ Glimmer HTML DSL Ruby code in the frontend:
39
43
 
40
44
  ```ruby
41
45
  require 'glimmer-dsl-web'
@@ -67,9 +71,9 @@ Screenshot:
67
71
 
68
72
  **Hello, Form!**
69
73
 
70
- [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web) gives access to all Web Browser built-in features like HTML form validations, input focus, events, and element functions from a very terse and productive Ruby GUI DSL.
74
+ [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web) gives access to all Web Browser built-in features like HTML form validations, input focus, events, and element functions from a very terse and productive Ruby HTML DSL. Also, you can apply CSS styles by including directly in Ruby code as a string, using [Glimmer DSL for CSS](https://github.com/AndyObtiva/glimmer-dsl-css), or managing CSS completely separately using something like [SCSS](https://sass-lang.com/). The CSS techniques could be combined as well, like by managing common reusable CSS styles separately in SCSS, but adding component specific CSS styles in Ruby when it is more convenient.
71
75
 
72
- Glimmer GUI code:
76
+ Glimmer HTML DSL Ruby code in the frontend:
73
77
 
74
78
  ```ruby
75
79
  require 'glimmer-dsl-web'
@@ -221,95 +225,11 @@ Screenshot:
221
225
 
222
226
  ![Hello, Form!](/images/glimmer-dsl-web-samples-hello-hello-form.gif)
223
227
 
224
- **Hello, Observer!**
225
-
226
- [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web) provides the `observe(model, attribute) { ... }` keyword to employ the [Observer Design Pattern](https://en.wikipedia.org/wiki/Observer_pattern) as per [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) (Model View Controller), enabling Views to observe Models and update themselves in response to changes. If the `observe` keyword is used from inside a [Component](#hello-component) (covered later), when the Component is removed or its top-level element is removed, the observer is automatically cleaned up. The need for such explicit observers is significantly diminished by the availablility of the more advanced Unidirectional [Data-Binding](#hello-data-binding) Support and Bidirectional [Data-Binding](#hello-data-binding) Support (covered later).
227
-
228
- Glimmer GUI code:
229
-
230
- ```ruby
231
- require 'glimmer-dsl-web'
232
-
233
- class NumberHolder
234
- attr_accessor :number
235
-
236
- def initialize
237
- self.number = 50
238
- end
239
- end
240
-
241
- class HelloObserver
242
- include Glimmer::Web::Component
243
-
244
- before_render do
245
- @number_holder = NumberHolder.new
246
- end
247
-
248
- after_render do
249
- @number_input.value = @number_holder.number
250
- @range_input.value = @number_holder.number
251
- # Observe Model attribute @number_holder.number for changes and update View
252
- # Observer is automatically cleaned up if remove method is called on rendered HelloObserver
253
- # or its top-level element
254
- observe(@number_holder, :number) do
255
- number_string = @number_holder.number.to_s
256
- @number_input.value = number_string unless @number_input.value == number_string
257
- @range_input.value = number_string unless @range_input.value == number_string
258
- end
259
- # Bidirectional Data-Binding does the same thing automatically
260
- # Just disable the observe block above as well as the oninput listeners below
261
- # and enable the `value <=> [@number_holder, :number]` lines to try the data-binding version
262
- # Learn more about Bidirectional and Unidirectional Data-Binding in hello_data_binding.rb
263
- end
264
-
265
- markup {
266
- div {
267
- div {
268
- @number_input = input(type: 'number', min: 0, max: 100) {
269
- # oninput listener updates Model attribute @number_holder.number
270
- oninput do
271
- @number_holder.number = @number_input.value.to_i
272
- end
273
-
274
- # Bidirectional Data-Binding simplifies the implementation significantly
275
- # by enabling the following line and disabling oninput listeners as well
276
- # as the after_body observe block observer
277
- # Learn more about Bidirectional and Unidirectional Data-Binding in hello_data_binding.rb
278
- # value <=> [@number_holder, :number]
279
- }
280
- }
281
- div {
282
- @range_input = input(type: 'range', min: 0, max: 100) {
283
- # oninput listener updates Model attribute @number_holder.number
284
- oninput do
285
- @number_holder.number = @range_input.value.to_i
286
- end
287
-
288
- # Bidirectional Data-Binding simplifies the implementation significantly
289
- # by enabling the following line and disabling oninput listeners as well
290
- # as the after_body observe block observer
291
- # Learn more about Bidirectional and Unidirectional Data-Binding in hello_data_binding.rb
292
- # value <=> [@number_holder, :number]
293
- }
294
- }
295
- }
296
- }
297
- end
298
-
299
- Document.ready? do
300
- HelloObserver.render
301
- end
302
- ```
303
-
304
- Screenshot:
305
-
306
- ![Hello, Observer!](/images/glimmer-dsl-web-samples-hello-hello-observer.gif)
307
-
308
228
  **Hello, Data-Binding!**
309
229
 
310
230
  [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web) intuitively supports both Unidirectional (One-Way) Data-Binding via the `<=` operator and Bidirectional (Two-Way) Data-Binding via the `<=>` operator, incredibly simplifying how to sync View properties with Model attributes with the simplest code to reason about.
311
231
 
312
- Glimmer GUI code:
232
+ Glimmer HTML DSL Ruby code in the frontend:
313
233
 
314
234
  ```ruby
315
235
  require 'glimmer-dsl-web'
@@ -428,7 +348,7 @@ If you need to regenerate HTML element content dynamically, you can use Content
428
348
  rebuild HTML elements based on changes in a Model attribute that provides the source data.
429
349
  In this example, we generate multiple address forms based on the number of addresses the user has.
430
350
 
431
- Glimmer GUI code:
351
+ Glimmer HTML DSL Ruby code in the frontend:
432
352
 
433
353
  ```ruby
434
354
  require 'glimmer-dsl-web'
@@ -559,13 +479,15 @@ Screenshot:
559
479
 
560
480
  You can define Glimmer web components (View components) to reuse visual concepts to your heart's content,
561
481
  by simply defining a class with `include Glimmer::Web::Component` and encasing the reusable markup inside
562
- a `markup {...}` block. Glimmer web components automatically extend the Glimmer GUI DSL with new keywords
563
- that match the underscored versions of the component class names (e.g. a `OrderSummary` class yields
564
- the `order_summary` keyword for reusing that component within the Glimmer GUI DSL).
565
- Below, we define an `AddressForm` component that generates a `address_form` keyword, and then we
482
+ a `markup {...}` block. Glimmer web components automatically extend the Glimmer HTML DSL with new keywords
483
+ that match the underscored versions of the component class names (e.g. an `OrderSummary` class yields
484
+ the `order_summary` keyword for reusing that component within the Glimmer HTML DSL).
485
+ You may insert a Glimmer component anywhere into a Rails View using `glimmer_component(component_path, *args)`
486
+ Rails helper (more about it in [Hello, glimmer_component Rails Helper!](#hello-glimmer_component-rails-helper)).
487
+ Below, we define an `AddressForm` component that generates an `address_form` keyword, and then we
566
488
  reuse it twice inside an `AddressPage` component displaying a Shipping Address and a Billing Address.
567
489
 
568
- Glimmer GUI code:
490
+ Glimmer HTML DSL Ruby code in the frontend:
569
491
 
570
492
  ```ruby
571
493
  require 'glimmer-dsl-web'
@@ -645,9 +567,9 @@ end
645
567
  # AddressForm Glimmer Web Component (View component)
646
568
  #
647
569
  # Including Glimmer::Web::Component makes this class a View component and automatically
648
- # generates a new Glimmer GUI DSL keyword that matches the lowercase underscored version
570
+ # generates a new Glimmer HTML DSL keyword that matches the lowercase underscored version
649
571
  # of the name of the class. AddressForm generates address_form keyword, which can be used
650
- # elsewhere in Glimmer GUI DSL code as done inside AddressPage below.
572
+ # elsewhere in Glimmer HTML DSL code as done inside AddressPage below.
651
573
  class AddressForm
652
574
  include Glimmer::Web::Component
653
575
 
@@ -814,7 +736,7 @@ Rails View code:
814
736
  </div>
815
737
  ```
816
738
 
817
- Glimmer GUI code:
739
+ Glimmer HTML DSL Ruby code in the frontend (`app/assets/opal/address_form.rb`):
818
740
 
819
741
  ```ruby
820
742
  require 'glimmer-dsl-web'
@@ -979,9 +901,9 @@ Screenshot:
979
901
 
980
902
  **Hello, Paragraph!**
981
903
 
982
- To facilitate building formatted textual paragraphs in Ruby, the Glimmer GUI DSL is advanced enough to behave differently when using HTML formatting elements: `<br>`, `<strong>`, `<em>`, `<br>`, `<i>`, `<sub>`, `<sup>`, `<del>`, `<ins>`, `<small>`, `<mark>`
904
+ To facilitate building formatted textual paragraphs in Ruby, thanks to [Glimmer](https://github.com/AndyObtiva/glimmer#dsl-engine), the most advanced DSL engine in Ruby, the Glimmer HTML DSL is advanced enough to intelligently behave differently under different situations, like when using HTML formatting elements: `<br>`, `<strong>`, `<em>`, `<br>`, `<i>`, `<sub>`, `<sup>`, `<del>`, `<ins>`, `<small>`, `<mark>`
983
905
 
984
- Instead of returning Ruby objects that are nested as children within their parent, the Glimmer GUI DSL returns `String` objects directly that can be concatenated to or embedded within other `String` objects via interpolation.
906
+ Instead of returning Ruby objects that are nested as children within their parent, the Glimmer HTML DSL returns `String` objects directly that can be concatenated to or embedded within other `String` objects via interpolation.
985
907
 
986
908
  This enables writing code like:
987
909
 
@@ -1009,9 +931,9 @@ it returns a `String` to enable code like this:
1009
931
 
1010
932
  `p {"#{span('Yesterday, ', style: 'text-decoration: underline;')}Robert suggested adding a new #{em('feature', class: 'very-emphasized')} to our software product.#{br}}`
1011
933
 
1012
- In any case, below is a full example leveraging the Glimmer GUI DSL alternative approach when utilizing formatting elements underneath a paragraph.
934
+ In any case, below is a full example leveraging the Glimmer HTML DSL alternative approach when utilizing formatting elements underneath a paragraph.
1013
935
 
1014
- Glimmer GUI code:
936
+ Glimmer HTML DSL Ruby code in the frontend:
1015
937
 
1016
938
  ```ruby
1017
939
  require 'glimmer-dsl-web'
@@ -1068,6 +990,92 @@ Screenshot:
1068
990
 
1069
991
  ![Hello, Paragraph!](/images/glimmer-dsl-web-samples-hello-hello-paragraph.png)
1070
992
 
993
+ **Hello, Observer!**
994
+
995
+ [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web) provides the `observe(model, attribute) { ... }` keyword to employ the [Observer Design Pattern](https://en.wikipedia.org/wiki/Observer_pattern) as per [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) (Model View Controller), enabling Views to observe Models and update themselves in response to changes. If the `observe` keyword is used from inside a [Component](#hello-component), when the Component is removed or its top-level element is removed, the observer is automatically cleaned up. The need for such explicit observers is significantly diminished by the availablility of the more advanced Unidirectional [Data-Binding](#hello-data-binding) Support and Bidirectional [Data-Binding](#hello-data-binding) Support.
996
+
997
+ Glimmer HTML DSL Ruby code in the frontend:
998
+
999
+ ```ruby
1000
+ require 'glimmer-dsl-web'
1001
+
1002
+ class NumberHolder
1003
+ attr_accessor :number
1004
+
1005
+ def initialize
1006
+ self.number = 50
1007
+ end
1008
+ end
1009
+
1010
+ class HelloObserver
1011
+ include Glimmer::Web::Component
1012
+
1013
+ before_render do
1014
+ @number_holder = NumberHolder.new
1015
+ end
1016
+
1017
+ after_render do
1018
+ @number_input.value = @number_holder.number
1019
+ @range_input.value = @number_holder.number
1020
+ # Observe Model attribute @number_holder.number for changes and update View
1021
+ # Observer is automatically cleaned up if remove method is called on rendered HelloObserver
1022
+ # or its top-level element
1023
+ observe(@number_holder, :number) do
1024
+ number_string = @number_holder.number.to_s
1025
+ @number_input.value = number_string unless @number_input.value == number_string
1026
+ @range_input.value = number_string unless @range_input.value == number_string
1027
+ end
1028
+ # Bidirectional Data-Binding does the same thing automatically
1029
+ # Just disable the observe block above as well as the oninput listeners below
1030
+ # and enable the `value <=> [@number_holder, :number]` lines to try the data-binding version
1031
+ # Learn more about Bidirectional and Unidirectional Data-Binding in hello_data_binding.rb
1032
+ end
1033
+
1034
+ markup {
1035
+ div {
1036
+ div {
1037
+ @number_input = input(type: 'number', min: 0, max: 100) {
1038
+ # oninput listener updates Model attribute @number_holder.number
1039
+ oninput do
1040
+ @number_holder.number = @number_input.value.to_i
1041
+ end
1042
+
1043
+ # Bidirectional Data-Binding simplifies the implementation significantly
1044
+ # by enabling the following line and disabling oninput listeners as well
1045
+ # as the after_body observe block observer
1046
+ # Learn more about Bidirectional and Unidirectional Data-Binding in hello_data_binding.rb
1047
+ # value <=> [@number_holder, :number]
1048
+ }
1049
+ }
1050
+ div {
1051
+ @range_input = input(type: 'range', min: 0, max: 100) {
1052
+ # oninput listener updates Model attribute @number_holder.number
1053
+ oninput do
1054
+ @number_holder.number = @range_input.value.to_i
1055
+ end
1056
+
1057
+ # Bidirectional Data-Binding simplifies the implementation significantly
1058
+ # by enabling the following line and disabling oninput listeners as well
1059
+ # as the after_body observe block observer
1060
+ # Learn more about Bidirectional and Unidirectional Data-Binding in hello_data_binding.rb
1061
+ # value <=> [@number_holder, :number]
1062
+ }
1063
+ }
1064
+ }
1065
+ }
1066
+ end
1067
+
1068
+ Document.ready? do
1069
+ HelloObserver.render
1070
+ end
1071
+ ```
1072
+
1073
+ Screenshot:
1074
+
1075
+ ![Hello, Observer!](/images/glimmer-dsl-web-samples-hello-hello-observer.gif)
1076
+
1077
+ To get started, [Setup](#setup) Ruby gem, read [Usage](#usage) instructions, and check out more [Samples](#samples) (including playing around with a [Rails sample app](https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app)).
1078
+
1071
1079
  --
1072
1080
 
1073
1081
  NOTE: Glimmer DSL for Web is a Beta project. If you want it developed faster, please [open an issue report](https://github.com/AndyObtiva/glimmer-dsl-web/issues/new). I have completed some GitHub project features much faster before due to [issue reports](https://github.com/AndyObtiva/glimmer-dsl-web/issues) and [pull requests](https://github.com/AndyObtiva/glimmer-dsl-web/pulls). Please help make better by contributing, adopting for small or low risk projects, and providing feedback. It is still a Beta, so the more feedback and issues you report the better.
@@ -1081,6 +1089,9 @@ Learn more about the differences between various [Glimmer](https://github.com/An
1081
1089
  - [Glimmer DSL for Web](#)
1082
1090
  - [Prerequisites](#prerequisites)
1083
1091
  - [Setup](#setup)
1092
+ - [Rails 7](#rails-7)
1093
+ - [Rails 6](#rails-6)
1094
+ - [Standalone (No Rails)](#standalone-no-rails)
1084
1095
  - [Usage](#usage)
1085
1096
  - [Supported Glimmer DSL Keywords](#supported-glimmer-dsl-keywords)
1086
1097
  - [Coming from Glimmer DSL for Opal](#coming-from-glimmer-dsl-for-opal)
@@ -1114,17 +1125,17 @@ Learn more about the differences between various [Glimmer](https://github.com/An
1114
1125
  [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web) will begin by supporting [Opal Ruby](https://opalrb.com/) on [Rails](https://rubyonrails.org/). [Opal](https://opalrb.com/) is a lightweight Ruby to JavaScript transpiler that results in small downloadables compared to WASM. In the future, the project might grow to support [Ruby WASM](https://github.com/ruby/ruby.wasm) as an alternative to [Opal Ruby](https://opalrb.com/) that could be switched to with a simple configuration change.
1115
1126
 
1116
1127
  - Ruby 3.0+
1117
- - Rails 6-7: [https://github.com/rails/rails](https://github.com/rails/rails)
1128
+ - Rails 7: [https://github.com/rails/rails](https://github.com/rails/rails)
1118
1129
 
1119
1130
  ## Setup
1120
1131
 
1121
- (NOTE: Keep in mind this is a Beta. If you run into issues, try to go back to a [previous revision](https://rubygems.org/gems/glimmer-dsl-web/versions). Also, there is a slight chance any issues you encounter are fixed in master or some other branch that you could check out instead)
1132
+ You can setup Glimmer DSL for Web in [Rails 7](#rails-7), [Rails 6](#rails-6), or [Standalone (No Rails)](#standalone-no-rails).
1122
1133
 
1123
- The [glimmer-dsl-web](https://rubygems.org/gems/glimmer-dsl-web) gem is a [Rails Engine](https://guides.rubyonrails.org/engines.html) gem that includes assets.
1134
+ (NOTE: Keep in mind this is a Beta. If you run into issues, try to go back to a [previous revision](https://rubygems.org/gems/glimmer-dsl-web/versions). Also, there is a slight chance any issues you encounter are fixed in master or some other branch that you could check out instead)
1124
1135
 
1125
1136
  ### Rails 7
1126
1137
 
1127
- Please follow the following steps to setup.
1138
+ Please follow these steps to setup.
1128
1139
 
1129
1140
  Install a Rails 7 gem:
1130
1141
 
@@ -1141,7 +1152,7 @@ rails new glimmer_app_server
1141
1152
  Add the following to `Gemfile`:
1142
1153
 
1143
1154
  ```
1144
- gem 'glimmer-dsl-web', '~> 0.2.2'
1155
+ gem 'glimmer-dsl-web', '~> 0.2.4'
1145
1156
  ```
1146
1157
 
1147
1158
  Run:
@@ -1158,7 +1169,7 @@ Follow [opal-rails](https://github.com/opal/opal-rails) instructions, basically
1158
1169
  bin/rails g opal:install
1159
1170
  ```
1160
1171
 
1161
- To enable the `glimmer-dsl-web` library in the frontend, edit `config/initializers/assets.rb` and add the following at the bottom:
1172
+ To enable the `glimmer-dsl-web` gem in the frontend, edit `config/initializers/assets.rb` and add the following at the bottom:
1162
1173
 
1163
1174
  ```ruby
1164
1175
  Opal.use_gem 'glimmer-dsl-web'
@@ -1168,9 +1179,11 @@ Opal.append_path Rails.root.join('app', 'assets', 'opal')
1168
1179
  To enable Opal Browser Debugging in Ruby with the [Source Maps](https://opalrb.com/docs/guides/v1.4.1/source_maps.html) feature, edit `config/initializers/opal.rb` and add the following inside the `Rails.application.configure do; end` block at the bottom of it:
1169
1180
 
1170
1181
  ```ruby
1171
- config.assets.debug = true
1182
+ config.assets.debug = true if Rails.env.development?
1172
1183
  ```
1173
1184
 
1185
+ Assuming this is a brand new Rails application and you do not have any Rails resources, you can scaffold the welcome resource just for testing purposes.
1186
+
1174
1187
  Run:
1175
1188
 
1176
1189
  ```
@@ -1212,7 +1225,7 @@ Edit and replace `app/assets/opal/opal_application.rb` content with code below (
1212
1225
  ```ruby
1213
1226
  require 'glimmer-dsl-web' # brings opal and other dependencies automatically
1214
1227
 
1215
- # Add more require-statements or Glimmer GUI DSL code
1228
+ # Add more require-statements or Glimmer HTML DSL code
1216
1229
  ```
1217
1230
 
1218
1231
  ```ruby
@@ -1221,7 +1234,7 @@ require 'glimmer-dsl-web'
1221
1234
  require 'glimmer-dsl-web/samples/hello/hello_world.rb'
1222
1235
  ```
1223
1236
 
1224
- If the `<body></body>` element (where the Glimmer GUI DSL adds elements by default) is not available when the JS file is loading, you need to put the code inside a `Document.ready? do; end` (but, it is recommended that you load the JS file after the parent element like `<body></body>` is in the page already for faster performance, which is guaranteed automatically by using `glimmer_component`, mentioned in details below):
1237
+ If the `<body></body>` element (where the Glimmer HTML DSL adds elements by default) is not available when the JS file is loading, you need to put the code inside a `Document.ready? do; end` (but, it is recommended that you load the JS file after the parent element like `<body></body>` is in the page already for faster performance, which is guaranteed automatically by using `glimmer_component`, mentioned in details below):
1225
1238
 
1226
1239
  ```ruby
1227
1240
  require 'glimmer-dsl-web'
@@ -1233,7 +1246,7 @@ end
1233
1246
 
1234
1247
  Example to confirm setup is working:
1235
1248
 
1236
- Glimmer GUI code:
1249
+ Glimmer HTML DSL Ruby code in the frontend:
1237
1250
 
1238
1251
  ```ruby
1239
1252
  require 'glimmer-dsl-web'
@@ -1284,7 +1297,7 @@ HTML:
1284
1297
  ...
1285
1298
  ```
1286
1299
 
1287
- Glimmer GUI code:
1300
+ Glimmer HTML DSL Ruby code in the frontend:
1288
1301
 
1289
1302
  ```ruby
1290
1303
  require 'glimmer-dsl-web'
@@ -1337,9 +1350,11 @@ If you run into any issues in setup, refer to the [Sample Glimmer DSL for Web Ra
1337
1350
 
1338
1351
  Otherwise, if you still cannot setup successfully (even with the help of the sample project, or if the sample project stops working), please do not hesitate to report an [Issue request](https://github.com/AndyObtiva/glimmer-dsl-web/issues) or fix and submit a [Pull Request](https://github.com/AndyObtiva/glimmer-dsl-web/pulls).
1339
1352
 
1353
+ Next, read [Usage](#usage) instructions, and check out [Samples](#samples).
1354
+
1340
1355
  ### Rails 6
1341
1356
 
1342
- Please follow the following steps to setup.
1357
+ Please follow these steps to setup.
1343
1358
 
1344
1359
  Install a Rails 6 gem:
1345
1360
 
@@ -1362,7 +1377,7 @@ Disable the `webpacker` gem line in `Gemfile`:
1362
1377
  Add the following to `Gemfile`:
1363
1378
 
1364
1379
  ```ruby
1365
- gem 'glimmer-dsl-web', '~> 0.2.2'
1380
+ gem 'glimmer-dsl-web', '~> 0.2.4'
1366
1381
  ```
1367
1382
 
1368
1383
  Run:
@@ -1379,7 +1394,7 @@ Follow [opal-rails](https://github.com/opal/opal-rails) instructions, basically
1379
1394
  bin/rails g opal:install
1380
1395
  ```
1381
1396
 
1382
- To enable the `glimmer-dsl-web` library in the frontend, edit `config/initializers/assets.rb` and add the following at the bottom:
1397
+ To enable the `glimmer-dsl-web` gem in the frontend, edit `config/initializers/assets.rb` and add the following at the bottom:
1383
1398
 
1384
1399
  ```ruby
1385
1400
  Opal.use_gem 'glimmer-dsl-web'
@@ -1389,9 +1404,11 @@ Opal.append_path Rails.root.join('app', 'assets', 'opal')
1389
1404
  To enable Opal Browser Debugging in Ruby with the [Source Maps](https://opalrb.com/docs/guides/v1.4.1/source_maps.html) feature, edit `config/initializers/opal.rb` and add the following inside the `Rails.application.configure do; end` block at the bottom of it:
1390
1405
 
1391
1406
  ```ruby
1392
- config.assets.debug = true
1407
+ config.assets.debug = true if Rails.env.development?
1393
1408
  ```
1394
1409
 
1410
+ Assuming this is a brand new Rails application and you do not have any Rails resources, you can scaffold the welcome resource just for testing purposes.
1411
+
1395
1412
  Run:
1396
1413
 
1397
1414
  ```
@@ -1439,7 +1456,7 @@ Edit and replace `app/assets/opal/opal_application.rb` content with code below (
1439
1456
  ```ruby
1440
1457
  require 'glimmer-dsl-web' # brings opal and other dependencies automatically
1441
1458
 
1442
- # Add more require-statements or Glimmer GUI DSL code
1459
+ # Add more require-statements or Glimmer HTML DSL code
1443
1460
  ```
1444
1461
 
1445
1462
  Example to confirm setup is working:
@@ -1453,7 +1470,7 @@ Initial HTML Markup:
1453
1470
  ...
1454
1471
  ```
1455
1472
 
1456
- Glimmer GUI code:
1473
+ Glimmer HTML DSL Ruby code in the frontend:
1457
1474
 
1458
1475
  ```ruby
1459
1476
  require 'glimmer-dsl-web'
@@ -1519,9 +1536,17 @@ If you run into any issues in setup, refer to the [Sample Glimmer DSL for Web Ra
1519
1536
 
1520
1537
  Otherwise, if you still cannot setup successfully (even with the help of the sample project, or if the sample project stops working), please do not hesitate to report an [Issue request](https://github.com/AndyObtiva/glimmer-dsl-web/issues) or fix and submit a [Pull Request](https://github.com/AndyObtiva/glimmer-dsl-web/pulls).
1521
1538
 
1539
+ Next, read [Usage](#usage) instructions, and check out [Samples](#samples).
1540
+
1541
+ ### Standalone (No Rails)
1542
+
1543
+ Andreas Idogawa-Wildi ([@Largo](https://github.com/Largo)) created a project that demonstrates how to use Glimmer DSL for Web standalone (without Rails):
1544
+
1545
+ [https://github.com/Largo/glimmer-dsl-web-standalone-demo](https://github.com/Largo/glimmer-dsl-web-standalone-demo)
1546
+
1522
1547
  ## Usage
1523
1548
 
1524
- Glimmer DSL for Web offers a GUI DSL for building HTML Web User Interfaces declaratively in Ruby.
1549
+ Glimmer DSL for Web offers a HTML DSL ([Graphical User Interface](https://en.wikipedia.org/wiki/Graphical_user_interface) [Domain Specific Language](https://en.wikipedia.org/wiki/Domain-specific_language)) for building HTML Web User Interfaces declaratively in Ruby.
1525
1550
 
1526
1551
  1- **Keywords (HTML Elements)**
1527
1552
 
@@ -1537,7 +1562,7 @@ Also, if the element has a little bit of text content that can fit in one line,
1537
1562
 
1538
1563
  3- **Content Block (Properties + Listeners + Nested Elements + Text Content)**
1539
1564
 
1540
- Element methods can accept a Ruby content block. It intentionally has a `{...}` style even as a multi-line block to indicate that the code is declarative GUI structure code (intentionally breaking away from Ruby imperative code conventions given this is a declarative GUI DSL, meaning a different language that has its own conventions, embedded within Ruby).
1565
+ Element methods can accept a Ruby content block. It intentionally has a `{...}` style even as a multi-line block to indicate that the code is declarative HTML DSL structure code (intentionally breaking away from Ruby imperative code conventions given this is a declarative HTML DSL ([Domain Specific Language](https://en.wikipedia.org/wiki/Domain-specific_language)), meaning a different language that has its own conventions, embedded within Ruby).
1541
1566
 
1542
1567
  You can nest HTML element properties under an element like:
1543
1568
 
@@ -1557,7 +1582,7 @@ button('Add') {
1557
1582
  }
1558
1583
  ```
1559
1584
 
1560
- Given that listener code is imperative, it uses a `do; end` style for Ruby blocks to separate it from declarative GUI structure code and enable quicker readability of the code.
1585
+ Given that listener code is imperative, it uses a `do; end` style for Ruby blocks to separate it from declarative HTML DSL structure code and enable quicker readability of the code.
1561
1586
 
1562
1587
  You can nest other HTML elements under an HTML element the same way you do so in HTML, like:
1563
1588
 
@@ -1591,6 +1616,8 @@ p(class: 'summary') {
1591
1616
 
1592
1617
  You can get/set any element property or invoke any element function by simply calling the lowercase underscored version of their name in Ruby like `input.check_validity`, `input.value`, and `input.id`.
1593
1618
 
1619
+ Next, check out [Samples](#samples).
1620
+
1594
1621
  ## Supported Glimmer DSL Keywords
1595
1622
 
1596
1623
  [All HTML elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Element), following the Ruby method name standard of lowercase and underscored names.
@@ -1601,7 +1628,7 @@ You can get/set any element property or invoke any element function by simply ca
1601
1628
 
1602
1629
  ## Coming from Glimmer DSL for Opal
1603
1630
 
1604
- This project is inspired by [Glimmer DSL for Opal](https://github.com/AndyObtiva/glimmer-dsl-opal) and is similar in enabling frontend GUI development with Ruby. [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web) mainly differs from Glimmer DSL for Opal by adopting a DSL that follows web-like HTML syntax in Ruby to facilitate leveraging existing HTML/CSS/JS skills instead of adopting a desktop GUI DSL that is webified. As a result, applications written in Glimmer DSL for Opal are not compatible with Glimmer DSL for Web.
1631
+ This project is inspired by [Glimmer DSL for Opal](https://github.com/AndyObtiva/glimmer-dsl-opal) and is similar in enabling Web Frontend development with Ruby. [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web) mainly differs from Glimmer DSL for Opal by adopting a DSL that follows web-like HTML syntax in Ruby to facilitate leveraging existing HTML/CSS/JS skills instead of adopting a desktop HTML DSL that is webified. As a result, applications written in Glimmer DSL for Opal are not compatible with Glimmer DSL for Web.
1605
1632
 
1606
1633
  ## Samples
1607
1634
 
@@ -1613,7 +1640,7 @@ https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app
1613
1640
 
1614
1641
  #### Hello, World!
1615
1642
 
1616
- Glimmer GUI code:
1643
+ Glimmer HTML DSL Ruby code in the frontend:
1617
1644
 
1618
1645
  ```ruby
1619
1646
  require 'glimmer-dsl-web'
@@ -1659,11 +1686,13 @@ That produces the following under `<body></body>`:
1659
1686
 
1660
1687
  ![setup is working](/images/glimmer-dsl-web-setup-example-working.png)
1661
1688
 
1689
+ You can also mount the `div` elsewhere by passing the `parent: parent_css_selector` option (e.g. `div(parent: 'div#app-container') { 'Hello, World!' }`).
1690
+
1662
1691
  #### Hello, Button!
1663
1692
 
1664
- Event listeners can be setup on any element using the same event names used in HTML (e.g. `onclick`) while passing in a standard Ruby block to handle behavior. `$$` gives access to `window` to invoke functions like `alert`.
1693
+ Event listeners can be setup on any element using the same event names used in HTML (e.g. `onclick`) while passing in a standard Ruby block to handle behavior. `$$` gives access to JS global scope from Ruby to invoke functions like `alert`.
1665
1694
 
1666
- Glimmer GUI code:
1695
+ Glimmer HTML DSL Ruby code in the frontend:
1667
1696
 
1668
1697
  ```ruby
1669
1698
  require 'glimmer-dsl-web'
@@ -1695,9 +1724,9 @@ Screenshot:
1695
1724
 
1696
1725
  #### Hello, Form!
1697
1726
 
1698
- [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web) gives access to all Web Browser built-in features like HTML form validations, input focus, events, and element functions from a very terse and productive Ruby GUI DSL.
1727
+ [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web) gives access to all Web Browser built-in features like HTML form validations, input focus, events, and element functions from a very terse and productive Ruby HTML DSL. Also, you can apply CSS styles by including directly in Ruby code as a string, using [Glimmer DSL for CSS](https://github.com/AndyObtiva/glimmer-dsl-css), or managing CSS completely separately using something like [SCSS](https://sass-lang.com/). The CSS techniques could be combined as well, like by managing common reusable CSS styles separately in SCSS, but adding component specific CSS styles in Ruby when it is more convenient.
1699
1728
 
1700
- Glimmer GUI code:
1729
+ Glimmer HTML DSL Ruby code in the frontend:
1701
1730
 
1702
1731
  ```ruby
1703
1732
  require 'glimmer-dsl-web'
@@ -1851,9 +1880,9 @@ Screenshot:
1851
1880
 
1852
1881
  #### Hello, Observer!
1853
1882
 
1854
- [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web) provides the `observe(model, attribute) { ... }` keyword to employ the [Observer Design Pattern](https://en.wikipedia.org/wiki/Observer_pattern) as per [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) (Model View Controller), enabling Views to observe Models and update themselves in response to changes. If the `observe` keyword is used from inside a [Component](#hello-component) (covered later), when the Component is removed or its top-level element is removed, the observer is automatically cleaned up. The need for such explicit observers is significantly diminished by the availablility of the more advanced Unidirectional [Data-Binding](#hello-data-binding) Support and Bidirectional [Data-Binding](#hello-data-binding) Support (covered later).
1883
+ [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web) provides the `observe(model, attribute) { ... }` keyword to employ the [Observer Design Pattern](https://en.wikipedia.org/wiki/Observer_pattern) as per [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) (Model View Controller), enabling Views to observe Models and update themselves in response to changes. If the `observe` keyword is used from inside a [Component](#hello-component), when the Component is removed or its top-level element is removed, the observer is automatically cleaned up. The need for such explicit observers is significantly diminished by the availablility of the more advanced Unidirectional [Data-Binding](#hello-data-binding) Support and Bidirectional [Data-Binding](#hello-data-binding) Support.
1855
1884
 
1856
- Glimmer GUI code:
1885
+ Glimmer HTML DSL Ruby code in the frontend:
1857
1886
 
1858
1887
  ```ruby
1859
1888
  require 'glimmer-dsl-web'
@@ -1937,7 +1966,7 @@ Screenshot:
1937
1966
 
1938
1967
  [Glimmer DSL for Web](https://rubygems.org/gems/glimmer-dsl-web) intuitively supports both Unidirectional (One-Way) Data-Binding via the `<=` operator and Bidirectional (Two-Way) Data-Binding via the `<=>` operator, incredibly simplifying how to sync View properties with Model attributes with the simplest code to reason about.
1939
1968
 
1940
- Glimmer GUI code:
1969
+ Glimmer HTML DSL Ruby code in the frontend:
1941
1970
 
1942
1971
  ```ruby
1943
1972
  require 'glimmer-dsl-web'
@@ -2110,7 +2139,7 @@ If you need to regenerate HTML element content dynamically, you can use Content
2110
2139
  rebuild HTML elements based on changes in a Model attribute that provides the source data.
2111
2140
  In this example, we generate multiple address forms based on the number of addresses the user has.
2112
2141
 
2113
- Glimmer GUI code:
2142
+ Glimmer HTML DSL Ruby code in the frontend:
2114
2143
 
2115
2144
  ```ruby
2116
2145
  require 'glimmer-dsl-web'
@@ -2241,13 +2270,15 @@ Screenshot:
2241
2270
 
2242
2271
  You can define Glimmer web components (View components) to reuse visual concepts to your heart's content,
2243
2272
  by simply defining a class with `include Glimmer::Web::Component` and encasing the reusable markup inside
2244
- a `markup {...}` block. Glimmer web components automatically extend the Glimmer GUI DSL with new keywords
2245
- that match the underscored versions of the component class names (e.g. a `OrderSummary` class yields
2246
- the `order_summary` keyword for reusing that component within the Glimmer GUI DSL).
2247
- Below, we define an `AddressForm` component that generates a `address_form` keyword, and then we
2273
+ a `markup {...}` block. Glimmer web components automatically extend the Glimmer HTML DSL with new keywords
2274
+ that match the underscored versions of the component class names (e.g. an `OrderSummary` class yields
2275
+ the `order_summary` keyword for reusing that component within the Glimmer HTML DSL).
2276
+ You may insert a Glimmer component anywhere into a Rails View using `glimmer_component(component_path, *args)`
2277
+ Rails helper (more about it in [Hello, glimmer_component Rails Helper!](#hello-glimmer_component-rails-helper)).
2278
+ Below, we define an `AddressForm` component that generates an `address_form` keyword, and then we
2248
2279
  reuse it twice inside an `AddressPage` component displaying a Shipping Address and a Billing Address.
2249
2280
 
2250
- Glimmer GUI code:
2281
+ Glimmer HTML DSL Ruby code in the frontend:
2251
2282
 
2252
2283
  ```ruby
2253
2284
  require 'glimmer-dsl-web'
@@ -2327,9 +2358,9 @@ end
2327
2358
  # AddressForm Glimmer Web Component (View component)
2328
2359
  #
2329
2360
  # Including Glimmer::Web::Component makes this class a View component and automatically
2330
- # generates a new Glimmer GUI DSL keyword that matches the lowercase underscored version
2361
+ # generates a new Glimmer HTML DSL keyword that matches the lowercase underscored version
2331
2362
  # of the name of the class. AddressForm generates address_form keyword, which can be used
2332
- # elsewhere in Glimmer GUI DSL code as done inside AddressPage below.
2363
+ # elsewhere in Glimmer HTML DSL code as done inside AddressPage below.
2333
2364
  class AddressForm
2334
2365
  include Glimmer::Web::Component
2335
2366
 
@@ -2496,7 +2527,7 @@ Rails View code:
2496
2527
  </div>
2497
2528
  ```
2498
2529
 
2499
- Glimmer GUI code:
2530
+ Glimmer HTML DSL Ruby code in the frontend (`app/assets/opal/address_form.rb`):
2500
2531
 
2501
2532
  ```ruby
2502
2533
  require 'glimmer-dsl-web'
@@ -2661,9 +2692,9 @@ Screenshot:
2661
2692
 
2662
2693
  #### Hello, Paragraph!
2663
2694
 
2664
- To facilitate building formatted textual paragraphs in Ruby, the Glimmer GUI DSL is advanced enough to behave differently when using HTML formatting elements: `<br>`, `<strong>`, `<em>`, `<br>`, `<i>`, `<sub>`, `<sup>`, `<del>`, `<ins>`, `<small>`, `<mark>`
2695
+ To facilitate building formatted textual paragraphs in Ruby, thanks to [Glimmer](https://github.com/AndyObtiva/glimmer#dsl-engine), the most advanced DSL engine in Ruby, the Glimmer HTML DSL is advanced enough to intelligently behave differently under different situations, like when using HTML formatting elements: `<br>`, `<strong>`, `<em>`, `<br>`, `<i>`, `<sub>`, `<sup>`, `<del>`, `<ins>`, `<small>`, `<mark>`
2665
2696
 
2666
- Instead of returning Ruby objects that are nested as children within their parent, the Glimmer GUI DSL returns `String` objects directly that can be concatenated to or embedded within other `String` objects via interpolation.
2697
+ Instead of returning Ruby objects that are nested as children within their parent, the Glimmer HTML DSL returns `String` objects directly that can be concatenated to or embedded within other `String` objects via interpolation.
2667
2698
 
2668
2699
  This enables writing code like:
2669
2700
 
@@ -2691,9 +2722,9 @@ it returns a `String` to enable code like this:
2691
2722
 
2692
2723
  `p {"#{span('Yesterday, ', style: 'text-decoration: underline;')}Robert suggested adding a new #{em('feature', class: 'very-emphasized')} to our software product.#{br}}`
2693
2724
 
2694
- In any case, below is a full example leveraging the Glimmer GUI DSL alternative approach when utilizing formatting elements underneath a paragraph.
2725
+ In any case, below is a full example leveraging the Glimmer HTML DSL alternative approach when utilizing formatting elements underneath a paragraph.
2695
2726
 
2696
- Glimmer GUI code:
2727
+ Glimmer HTML DSL Ruby code in the frontend:
2697
2728
 
2698
2729
  ```ruby
2699
2730
  require 'glimmer-dsl-web'
@@ -2754,7 +2785,7 @@ Screenshot:
2754
2785
 
2755
2786
  #### Hello, Input (Date/Time)!
2756
2787
 
2757
- Glimmer GUI code:
2788
+ Glimmer HTML DSL Ruby code in the frontend:
2758
2789
 
2759
2790
  ```ruby
2760
2791
  require 'glimmer-dsl-web'
@@ -2859,7 +2890,7 @@ Screenshot:
2859
2890
 
2860
2891
  #### Button Counter
2861
2892
 
2862
- Glimmer GUI code demonstrating MVC + Glimmer Web Components (Views) + Data-Binding:
2893
+ Glimmer HTML DSL Ruby code in the frontend demonstrating MVC + Glimmer Web Components (Views) + Data-Binding:
2863
2894
 
2864
2895
  ```ruby
2865
2896
  require 'glimmer-dsl-web'
@@ -2938,7 +2969,7 @@ Screenshot:
2938
2969
 
2939
2970
  - The Ruby Way (including TIMTOWTDI: There Is More Than One Way To Do It)
2940
2971
  - The Rails Way Convention over Configuration via smart defaults and automation of low-level details
2941
- - Requiring the least amount of syntax possible to build highly interactive web pages
2972
+ - Requiring the least amount of code possible to build highly interactive web pages
2942
2973
  - Declarative syntax that visually maps to the DOM (Document Object Model) hierarchy
2943
2974
  - Ability to mix declarative and imperative code conveniently in one language
2944
2975
  - Computers serve Software Engineers (not Software Engineers serve Computers)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.2
1
+ 0.2.4
@@ -2,17 +2,17 @@
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.2.2 ruby lib
5
+ # stub: glimmer-dsl-web 0.2.4 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "glimmer-dsl-web".freeze
9
- s.version = "0.2.2".freeze
9
+ s.version = "0.2.4"
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 = "2024-01-09"
15
- s.description = "Glimmer DSL for Web (Ruby in the Browser Web GUI Frontend Library) enables building Web GUI 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 library in existence. The library follows the Ruby way (with DSLs and TIMTOWTDI) and the Rails way (Convention over Configuration) while supporting 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. And, modular design is supported with Glimmer Web Components. You can finally live in pure Rubyland on the Web in both the frontend and backend with Glimmer DSL for Web! This library relies on Opal Ruby.".freeze
14
+ s.date = "2024-02-04"
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. And, modular design is supported with Glimmer Web Components. 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 = [
18
18
  "CHANGELOG.md",
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
30
30
  "lib/glimmer-dsl-web/ext/class.rb",
31
31
  "lib/glimmer-dsl-web/ext/date.rb",
32
32
  "lib/glimmer-dsl-web/ext/exception.rb",
33
+ "lib/glimmer-dsl-web/ext/kernel.rb",
33
34
  "lib/glimmer-dsl-web/samples/hello/hello_button.rb",
34
35
  "lib/glimmer-dsl-web/samples/hello/hello_component.rb",
35
36
  "lib/glimmer-dsl-web/samples/hello/hello_content_data_binding.rb",
@@ -54,10 +55,9 @@ Gem::Specification.new do |s|
54
55
  "lib/glimmer/dsl/web/general_element_expression.rb",
55
56
  "lib/glimmer/dsl/web/listener_expression.rb",
56
57
  "lib/glimmer/dsl/web/observe_expression.rb",
57
- "lib/glimmer/dsl/web/p_expression.rb",
58
58
  "lib/glimmer/dsl/web/property_expression.rb",
59
- "lib/glimmer/dsl/web/select_expression.rb",
60
59
  "lib/glimmer/dsl/web/shine_data_binding_expression.rb",
60
+ "lib/glimmer/dsl/web/span_expression.rb",
61
61
  "lib/glimmer/dsl/web/style_expression.rb",
62
62
  "lib/glimmer/helpers/glimmer_helper.rb",
63
63
  "lib/glimmer/util/proc_tracker.rb",
@@ -70,24 +70,24 @@ Gem::Specification.new do |s|
70
70
  ]
71
71
  s.homepage = "http://github.com/AndyObtiva/glimmer-dsl-web".freeze
72
72
  s.licenses = ["MIT".freeze]
73
- s.rubygems_version = "3.5.3".freeze
74
- s.summary = "Glimmer DSL for Web (Ruby in the Browser Web GUI Frontend Library)".freeze
73
+ s.rubygems_version = "3.4.10".freeze
74
+ s.summary = "Glimmer DSL for Web (Ruby in the Browser Web Frontend Framework)".freeze
75
75
 
76
76
  s.specification_version = 4
77
77
 
78
- s.add_runtime_dependency(%q<glimmer>.freeze, ["~> 2.7.6".freeze])
79
- s.add_runtime_dependency(%q<glimmer-dsl-xml>.freeze, ["~> 1.3.2".freeze])
80
- s.add_runtime_dependency(%q<glimmer-dsl-css>.freeze, ["~> 1.2.3".freeze])
81
- s.add_runtime_dependency(%q<opal>.freeze, ["= 1.8.2".freeze])
82
- s.add_runtime_dependency(%q<opal-rails>.freeze, ["= 2.0.3".freeze])
83
- s.add_runtime_dependency(%q<opal-async>.freeze, ["~> 1.4.1".freeze])
84
- s.add_runtime_dependency(%q<opal-jquery>.freeze, ["~> 0.5.1".freeze])
85
- s.add_runtime_dependency(%q<to_collection>.freeze, [">= 2.0.1".freeze, "< 3.0.0".freeze])
86
- s.add_development_dependency(%q<puts_debuggerer>.freeze, [">= 0".freeze])
87
- s.add_development_dependency(%q<rake>.freeze, [">= 10.1.0".freeze, "< 14.0.0".freeze])
88
- s.add_development_dependency(%q<rake-tui>.freeze, [">= 0".freeze])
89
- s.add_development_dependency(%q<jeweler>.freeze, [">= 2.3.9".freeze, "< 3.0.0".freeze])
90
- s.add_development_dependency(%q<rdoc>.freeze, [">= 6.2.1".freeze, "< 7.0.0".freeze])
91
- s.add_development_dependency(%q<opal-rspec>.freeze, ["~> 0.8.0.alpha2".freeze])
78
+ s.add_runtime_dependency(%q<glimmer>.freeze, ["~> 2.7.6"])
79
+ s.add_runtime_dependency(%q<glimmer-dsl-xml>.freeze, ["~> 1.3.2"])
80
+ s.add_runtime_dependency(%q<glimmer-dsl-css>.freeze, ["~> 1.2.3"])
81
+ s.add_runtime_dependency(%q<opal>.freeze, ["= 1.8.2"])
82
+ s.add_runtime_dependency(%q<opal-rails>.freeze, ["= 2.0.3"])
83
+ s.add_runtime_dependency(%q<opal-async>.freeze, ["~> 1.4.1"])
84
+ s.add_runtime_dependency(%q<opal-jquery>.freeze, ["~> 0.5.1"])
85
+ s.add_runtime_dependency(%q<to_collection>.freeze, [">= 2.0.1", "< 3.0.0"])
86
+ s.add_development_dependency(%q<puts_debuggerer>.freeze, [">= 0"])
87
+ s.add_development_dependency(%q<rake>.freeze, [">= 10.1.0", "< 14.0.0"])
88
+ s.add_development_dependency(%q<rake-tui>.freeze, [">= 0"])
89
+ s.add_development_dependency(%q<jeweler>.freeze, [">= 2.3.9", "< 3.0.0"])
90
+ s.add_development_dependency(%q<rdoc>.freeze, [">= 6.2.1", "< 7.0.0"])
91
+ s.add_development_dependency(%q<opal-rspec>.freeze, ["~> 0.8.0.alpha2"])
92
92
  end
93
93
 
@@ -24,8 +24,7 @@ require 'glimmer/dsl/web/element_expression'
24
24
  require 'glimmer/dsl/web/formatting_element_expression'
25
25
  require 'glimmer/dsl/web/listener_expression'
26
26
  require 'glimmer/dsl/web/property_expression'
27
- # require 'glimmer/dsl/web/p_expression'
28
- # require 'glimmer/dsl/web/select_expression'
27
+ require 'glimmer/dsl/web/span_expression'
29
28
  require 'glimmer/dsl/web/style_expression'
30
29
  require 'glimmer/dsl/web/bind_expression'
31
30
  require 'glimmer/dsl/web/data_binding_expression'
@@ -47,7 +46,6 @@ module Glimmer
47
46
  content_data_binding
48
47
  shine_data_binding
49
48
  formatting_element
50
- element
51
49
  ]
52
50
  )
53
51
  end
@@ -17,10 +17,14 @@ module Glimmer
17
17
  end
18
18
  end
19
19
 
20
+ module Kernel
21
+ alias pi p
22
+ end
23
+
20
24
  module Glimmer
21
25
  # Optimize performance through shortcut methods for all HTML elements that circumvent the DSL chain of responsibility
22
26
  element_expression = Glimmer::DSL::Web::ElementExpression.new
23
- (Glimmer::Web::ElementProxy::ELEMENT_KEYWORDS - ['style']).each do |keyword|
27
+ (Glimmer::Web::ElementProxy::ELEMENT_KEYWORDS - ['span', 'style']).each do |keyword|
24
28
  Glimmer::DSL::Engine.static_expressions[keyword] ||= Concurrent::Hash.new
25
29
  element_expression_dsl = element_expression.class.dsl
26
30
  Glimmer::DSL::Engine.static_expressions[keyword][element_expression_dsl] = element_expression
@@ -0,0 +1,17 @@
1
+ require 'glimmer/dsl/static_expression'
2
+ require 'glimmer/dsl/web/general_element_expression'
3
+
4
+ module Glimmer
5
+ module DSL
6
+ module Web
7
+ class SpanExpression < StaticExpression
8
+ include GeneralElementExpression
9
+
10
+ def can_interpret?(parent, keyword, *args, &block)
11
+ (parent.nil? ||
12
+ (parent.respond_to?(:keyword) && parent.keyword != 'p'))
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -316,11 +316,16 @@ module Glimmer
316
316
 
317
317
  # Returns content block if used as an attribute reader (no args)
318
318
  # Otherwise, if a block is passed, it adds it as content to this Glimmer web component
319
- def content(&block)
320
- if block_given?
321
- Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Web::ComponentExpression.new, self.class.keyword, &block)
319
+ def content(*args, &block)
320
+ if args.empty?
321
+ if block_given?
322
+ Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Web::ComponentExpression.new, self.class.keyword, &block)
323
+ else
324
+ @content
325
+ end
322
326
  else
323
- @content
327
+ # delegate to GUI DSL ContentExpression
328
+ super
324
329
  end
325
330
  end
326
331
 
@@ -371,6 +371,12 @@ module Glimmer
371
371
  @element_id ||= "element-#{ElementProxy.next_id_number_for(name)}"
372
372
  end
373
373
 
374
+ def class_name=(value)
375
+ value = value.is_a?(Array) ? value.join(' ') : value.to_s
376
+ new_class_name = "#{name} #{element_id} #{value}"
377
+ dom_element.prop('className', new_class_name)
378
+ end
379
+
374
380
  def add_css_class(css_class)
375
381
  dom_element.add_class(css_class)
376
382
  end
@@ -33,7 +33,7 @@ module Glimmer
33
33
  keyword = keyword.to_s
34
34
  (
35
35
  FORMATTING_ELEMENT_KEYWORDS.include?(keyword) ||
36
- (parent&.keyword == 'p' && keyword == 'span')
36
+ (keyword == 'span' && parent&.keyword == 'p')
37
37
  )
38
38
  end
39
39
 
@@ -0,0 +1,42 @@
1
+ # backtick_javascript: true
2
+
3
+ # Copyright (c) 2023-2024 Andy Maleh
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.
23
+
24
+ module ::Kernel
25
+ alias puts_without_glimmer puts
26
+ def puts(*strs)
27
+ puts_without_glimmer(*strs)
28
+ rescue Exception
29
+ strs.each do |str|
30
+ `console.log(#{str})`
31
+ end
32
+ end
33
+
34
+ alias p_without_glimmer p
35
+ def p(*args)
36
+ p_without_glimmer(*args)
37
+ rescue Exception
38
+ args.each do |arg|
39
+ `console.log(#{arg})`
40
+ end
41
+ end
42
+ end
@@ -96,9 +96,9 @@ end
96
96
  # AddressForm Glimmer Web Component (View component)
97
97
  #
98
98
  # Including Glimmer::Web::Component makes this class a View component and automatically
99
- # generates a new Glimmer GUI DSL keyword that matches the lowercase underscored version
99
+ # generates a new Glimmer HTML DSL keyword that matches the lowercase underscored version
100
100
  # of the name of the class. AddressForm generates address_form keyword, which can be used
101
- # elsewhere in Glimmer GUI DSL code as done inside AddressPage below.
101
+ # elsewhere in Glimmer HTML DSL code as done inside AddressPage below.
102
102
  class AddressForm
103
103
  include Glimmer::Web::Component
104
104
 
@@ -64,6 +64,7 @@ else
64
64
  require 'glimmer'
65
65
  require 'glimmer-dsl-web/ext/exception'
66
66
  require 'glimmer-dsl-web/ext/date'
67
+ require 'glimmer-dsl-web/ext/kernel'
67
68
 
68
69
  # Spiking async logging
69
70
  # logger = Glimmer::Config.logger
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.2.2
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-09 00:00:00.000000000 Z
11
+ date: 2024-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer
@@ -230,17 +230,21 @@ dependencies:
230
230
  - - "~>"
231
231
  - !ruby/object:Gem::Version
232
232
  version: 0.8.0.alpha2
233
- description: Glimmer DSL for Web (Ruby in the Browser Web GUI Frontend Library) enables
234
- building Web GUI frontends using Ruby in the Browser, as per Matz's recommendation
235
- in his RubyConf 2022 keynote speech to replace JavaScript with Ruby. It aims at
236
- providing the simplest, most intuitive, most straight-forward, and most productive
237
- frontend library in existence. The library follows the Ruby way (with DSLs and TIMTOWTDI)
238
- and the Rails way (Convention over Configuration) while supporting both Unidirectional
233
+ description: Glimmer DSL for Web (Ruby in the Browser Web Frontend Framework) enables
234
+ building Web Frontends using Ruby in the Browser, as per Matz's recommendation in
235
+ his RubyConf 2022 keynote speech to replace JavaScript with Ruby. It aims at providing
236
+ the simplest, most intuitive, most straight-forward, and most productive frontend
237
+ framework in existence. The framework follows the Ruby way (with DSLs and TIMTOWTDI)
238
+ and the Rails way (Convention over Configuration) in building Isomorphic Ruby on
239
+ Rails Applications. It provides a Ruby HTML DSL, which uniquely enables writing
240
+ both structure code and logic code in one language. It supports both Unidirectional
239
241
  (One-Way) Data-Binding (using <=) and Bidirectional (Two-Way) Data-Binding (using
240
242
  <=>). Dynamic rendering (and re-rendering) of HTML content is also supported via
241
243
  Content Data-Binding. And, modular design is supported with Glimmer Web Components.
242
- You can finally live in pure Rubyland on the Web in both the frontend and backend
243
- with Glimmer DSL for Web! This library relies on Opal Ruby.
244
+ Many samples are demonstrated in the Rails sample app (there is a very minimal Standalone
245
+ [No Rails] sample app too). You can finally live in pure Rubyland on the Web in
246
+ both the frontend and backend with Glimmer DSL for Web! This gem relies on Opal
247
+ Ruby.
244
248
  email: andy.am@gmail.com
245
249
  executables: []
246
250
  extensions: []
@@ -259,6 +263,7 @@ files:
259
263
  - lib/glimmer-dsl-web/ext/class.rb
260
264
  - lib/glimmer-dsl-web/ext/date.rb
261
265
  - lib/glimmer-dsl-web/ext/exception.rb
266
+ - lib/glimmer-dsl-web/ext/kernel.rb
262
267
  - lib/glimmer-dsl-web/samples/hello/hello_button.rb
263
268
  - lib/glimmer-dsl-web/samples/hello/hello_component.rb
264
269
  - lib/glimmer-dsl-web/samples/hello/hello_content_data_binding.rb
@@ -283,10 +288,9 @@ files:
283
288
  - lib/glimmer/dsl/web/general_element_expression.rb
284
289
  - lib/glimmer/dsl/web/listener_expression.rb
285
290
  - lib/glimmer/dsl/web/observe_expression.rb
286
- - lib/glimmer/dsl/web/p_expression.rb
287
291
  - lib/glimmer/dsl/web/property_expression.rb
288
- - lib/glimmer/dsl/web/select_expression.rb
289
292
  - lib/glimmer/dsl/web/shine_data_binding_expression.rb
293
+ - lib/glimmer/dsl/web/span_expression.rb
290
294
  - lib/glimmer/dsl/web/style_expression.rb
291
295
  - lib/glimmer/helpers/glimmer_helper.rb
292
296
  - lib/glimmer/util/proc_tracker.rb
@@ -315,8 +319,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
315
319
  - !ruby/object:Gem::Version
316
320
  version: '0'
317
321
  requirements: []
318
- rubygems_version: 3.5.3
322
+ rubygems_version: 3.4.10
319
323
  signing_key:
320
324
  specification_version: 4
321
- summary: Glimmer DSL for Web (Ruby in the Browser Web GUI Frontend Library)
325
+ summary: Glimmer DSL for Web (Ruby in the Browser Web Frontend Framework)
322
326
  test_files: []
@@ -1,12 +0,0 @@
1
- require 'glimmer/dsl/static_expression'
2
- require 'glimmer/dsl/web/general_element_expression'
3
-
4
- module Glimmer
5
- module DSL
6
- module Web
7
- class PExpression < StaticExpression
8
- include GeneralElementExpression
9
- end
10
- end
11
- end
12
- end
@@ -1,12 +0,0 @@
1
- require 'glimmer/dsl/static_expression'
2
- require 'glimmer/dsl/web/general_element_expression'
3
-
4
- module Glimmer
5
- module DSL
6
- module Web
7
- class SelectExpression < StaticExpression
8
- include GeneralElementExpression
9
- end
10
- end
11
- end
12
- end