glimmer-dsl-web 0.2.2 → 0.2.3

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: c418754ebdb0e40b75d62576c678942a321ee5d8b0dbb0f9d3bafbd4d0622cbb
4
+ data.tar.gz: a4e98d44358353332f166e3191bad00393532ac13dcbe0af214db53f91921b11
5
5
  SHA512:
6
- metadata.gz: 820828cc1d4f45fbc23df7e1296f71e24959fe811e5b380470cbc8126484ffe9bef70351eb4534777e7398f1bcd30363e30172ebe33b1828871318603fe5a906
7
- data.tar.gz: 52a96a0c75fc7cc57b8e6938784f75079f3b5caf3d4b5a49801604b8061aec73518a23576a7ab6346937f8d4899c70b0b6efa33faf9ae1d35c75cbded956101a
6
+ metadata.gz: d756e84e43ba8cce780251ab96c40234e2b5a9d53724b2be329d5cdef53d02d33a2ab629035a8c742d7ff75b888f76d2f8e92fcb5354a012bbdd061024c0db66
7
+ data.tar.gz: 221e1d4472510c02d403439d6fde7c33ace135f10337f2a258c1641d3685d41b8c5d049f2a96e99cbdad1dd2587c1728aa03bce04cb844705f083e2664bb49b0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.2.3
4
+
5
+ - Ensure that setting `element.class_name=classnameval` does not override its Glimmer built-in CSS classes
6
+ - 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.
7
+ - Remove `element` from dynamic part of Glimmer DSL to allow it to fail faster if an invalid HTML element name was used
8
+ - Fix use of `span` keyword under `p`, fixing Hello, Paragraph! sample.
9
+
3
10
  ## 0.2.2
4
11
 
5
12
  - 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)
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.3 (Beta)
2
2
  ## Ruby in the Browser Web GUI Frontend Library
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 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)) in building Isomorphic Ruby on Rails Applications. 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). 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 GUI 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 GUI code in the frontend:
39
43
 
40
44
  ```ruby
41
45
  require 'glimmer-dsl-web'
@@ -69,7 +73,7 @@ Screenshot:
69
73
 
70
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 GUI DSL.
71
75
 
72
- Glimmer GUI code:
76
+ Glimmer GUI 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 GUI 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 GUI code in the frontend:
432
352
 
433
353
  ```ruby
434
354
  require 'glimmer-dsl-web'
@@ -560,12 +480,14 @@ Screenshot:
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
482
  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
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 GUI 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 GUI code in the frontend:
569
491
 
570
492
  ```ruby
571
493
  require 'glimmer-dsl-web'
@@ -814,7 +736,7 @@ Rails View code:
814
736
  </div>
815
737
  ```
816
738
 
817
- Glimmer GUI code:
739
+ Glimmer GUI code in the frontend (`app/assets/opal/address_form.rb`):
818
740
 
819
741
  ```ruby
820
742
  require 'glimmer-dsl-web'
@@ -979,7 +901,7 @@ 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 GUI 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
906
  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.
985
907
 
@@ -1011,7 +933,7 @@ it returns a `String` to enable code like this:
1011
933
 
1012
934
  In any case, below is a full example leveraging the Glimmer GUI DSL alternative approach when utilizing formatting elements underneath a paragraph.
1013
935
 
1014
- Glimmer GUI code:
936
+ Glimmer GUI 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 GUI 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).
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.
@@ -1114,14 +1122,12 @@ Learn more about the differences between various [Glimmer](https://github.com/An
1114
1122
  [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
1123
 
1116
1124
  - Ruby 3.0+
1117
- - Rails 6-7: [https://github.com/rails/rails](https://github.com/rails/rails)
1125
+ - Rails 7: [https://github.com/rails/rails](https://github.com/rails/rails)
1118
1126
 
1119
1127
  ## Setup
1120
1128
 
1121
1129
  (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)
1122
1130
 
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.
1124
-
1125
1131
  ### Rails 7
1126
1132
 
1127
1133
  Please follow the following steps to setup.
@@ -1141,7 +1147,7 @@ rails new glimmer_app_server
1141
1147
  Add the following to `Gemfile`:
1142
1148
 
1143
1149
  ```
1144
- gem 'glimmer-dsl-web', '~> 0.2.2'
1150
+ gem 'glimmer-dsl-web', '~> 0.2.3'
1145
1151
  ```
1146
1152
 
1147
1153
  Run:
@@ -1168,9 +1174,11 @@ Opal.append_path Rails.root.join('app', 'assets', 'opal')
1168
1174
  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
1175
 
1170
1176
  ```ruby
1171
- config.assets.debug = true
1177
+ config.assets.debug = true if Rails.env.development?
1172
1178
  ```
1173
1179
 
1180
+ 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.
1181
+
1174
1182
  Run:
1175
1183
 
1176
1184
  ```
@@ -1233,7 +1241,7 @@ end
1233
1241
 
1234
1242
  Example to confirm setup is working:
1235
1243
 
1236
- Glimmer GUI code:
1244
+ Glimmer GUI code in the frontend:
1237
1245
 
1238
1246
  ```ruby
1239
1247
  require 'glimmer-dsl-web'
@@ -1284,7 +1292,7 @@ HTML:
1284
1292
  ...
1285
1293
  ```
1286
1294
 
1287
- Glimmer GUI code:
1295
+ Glimmer GUI code in the frontend:
1288
1296
 
1289
1297
  ```ruby
1290
1298
  require 'glimmer-dsl-web'
@@ -1337,6 +1345,8 @@ If you run into any issues in setup, refer to the [Sample Glimmer DSL for Web Ra
1337
1345
 
1338
1346
  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
1347
 
1348
+ Next, read [Usage](#usage) instructions, and check out [Samples](#samples).
1349
+
1340
1350
  ### Rails 6
1341
1351
 
1342
1352
  Please follow the following steps to setup.
@@ -1362,7 +1372,7 @@ Disable the `webpacker` gem line in `Gemfile`:
1362
1372
  Add the following to `Gemfile`:
1363
1373
 
1364
1374
  ```ruby
1365
- gem 'glimmer-dsl-web', '~> 0.2.2'
1375
+ gem 'glimmer-dsl-web', '~> 0.2.3'
1366
1376
  ```
1367
1377
 
1368
1378
  Run:
@@ -1389,9 +1399,11 @@ Opal.append_path Rails.root.join('app', 'assets', 'opal')
1389
1399
  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
1400
 
1391
1401
  ```ruby
1392
- config.assets.debug = true
1402
+ config.assets.debug = true if Rails.env.development?
1393
1403
  ```
1394
1404
 
1405
+ 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.
1406
+
1395
1407
  Run:
1396
1408
 
1397
1409
  ```
@@ -1453,7 +1465,7 @@ Initial HTML Markup:
1453
1465
  ...
1454
1466
  ```
1455
1467
 
1456
- Glimmer GUI code:
1468
+ Glimmer GUI code in the frontend:
1457
1469
 
1458
1470
  ```ruby
1459
1471
  require 'glimmer-dsl-web'
@@ -1519,9 +1531,11 @@ If you run into any issues in setup, refer to the [Sample Glimmer DSL for Web Ra
1519
1531
 
1520
1532
  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
1533
 
1534
+ Next, read [Usage](#usage) instructions, and check out [Samples](#samples).
1535
+
1522
1536
  ## Usage
1523
1537
 
1524
- Glimmer DSL for Web offers a GUI DSL for building HTML Web User Interfaces declaratively in Ruby.
1538
+ Glimmer DSL for Web offers a GUI 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
1539
 
1526
1540
  1- **Keywords (HTML Elements)**
1527
1541
 
@@ -1537,7 +1551,7 @@ Also, if the element has a little bit of text content that can fit in one line,
1537
1551
 
1538
1552
  3- **Content Block (Properties + Listeners + Nested Elements + Text Content)**
1539
1553
 
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).
1554
+ 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 ([Domain Specific Language](https://en.wikipedia.org/wiki/Domain-specific_language)), meaning a different language that has its own conventions, embedded within Ruby).
1541
1555
 
1542
1556
  You can nest HTML element properties under an element like:
1543
1557
 
@@ -1591,6 +1605,8 @@ p(class: 'summary') {
1591
1605
 
1592
1606
  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
1607
 
1608
+ Next, check out [Samples](#samples).
1609
+
1594
1610
  ## Supported Glimmer DSL Keywords
1595
1611
 
1596
1612
  [All HTML elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Element), following the Ruby method name standard of lowercase and underscored names.
@@ -1613,7 +1629,7 @@ https://github.com/AndyObtiva/sample-glimmer-dsl-web-rails7-app
1613
1629
 
1614
1630
  #### Hello, World!
1615
1631
 
1616
- Glimmer GUI code:
1632
+ Glimmer GUI code in the frontend:
1617
1633
 
1618
1634
  ```ruby
1619
1635
  require 'glimmer-dsl-web'
@@ -1659,11 +1675,13 @@ That produces the following under `<body></body>`:
1659
1675
 
1660
1676
  ![setup is working](/images/glimmer-dsl-web-setup-example-working.png)
1661
1677
 
1678
+ You can also mount the `div` elsewhere by passing the `parent: parent_css_selector` option (e.g. `div(parent: 'div#app-container') { 'Hello, World!' }`).
1679
+
1662
1680
  #### Hello, Button!
1663
1681
 
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`.
1682
+ 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
1683
 
1666
- Glimmer GUI code:
1684
+ Glimmer GUI code in the frontend:
1667
1685
 
1668
1686
  ```ruby
1669
1687
  require 'glimmer-dsl-web'
@@ -1697,7 +1715,7 @@ Screenshot:
1697
1715
 
1698
1716
  [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.
1699
1717
 
1700
- Glimmer GUI code:
1718
+ Glimmer GUI code in the frontend:
1701
1719
 
1702
1720
  ```ruby
1703
1721
  require 'glimmer-dsl-web'
@@ -1851,9 +1869,9 @@ Screenshot:
1851
1869
 
1852
1870
  #### Hello, Observer!
1853
1871
 
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).
1872
+ [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
1873
 
1856
- Glimmer GUI code:
1874
+ Glimmer GUI code in the frontend:
1857
1875
 
1858
1876
  ```ruby
1859
1877
  require 'glimmer-dsl-web'
@@ -1937,7 +1955,7 @@ Screenshot:
1937
1955
 
1938
1956
  [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
1957
 
1940
- Glimmer GUI code:
1958
+ Glimmer GUI code in the frontend:
1941
1959
 
1942
1960
  ```ruby
1943
1961
  require 'glimmer-dsl-web'
@@ -2110,7 +2128,7 @@ If you need to regenerate HTML element content dynamically, you can use Content
2110
2128
  rebuild HTML elements based on changes in a Model attribute that provides the source data.
2111
2129
  In this example, we generate multiple address forms based on the number of addresses the user has.
2112
2130
 
2113
- Glimmer GUI code:
2131
+ Glimmer GUI code in the frontend:
2114
2132
 
2115
2133
  ```ruby
2116
2134
  require 'glimmer-dsl-web'
@@ -2242,12 +2260,14 @@ Screenshot:
2242
2260
  You can define Glimmer web components (View components) to reuse visual concepts to your heart's content,
2243
2261
  by simply defining a class with `include Glimmer::Web::Component` and encasing the reusable markup inside
2244
2262
  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
2263
+ that match the underscored versions of the component class names (e.g. an `OrderSummary` class yields
2246
2264
  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
2265
+ You may insert a Glimmer component anywhere into a Rails View using `glimmer_component(component_path, *args)`
2266
+ Rails helper (more about it in [Hello, glimmer_component Rails Helper!](#hello-glimmer_component-rails-helper)).
2267
+ Below, we define an `AddressForm` component that generates an `address_form` keyword, and then we
2248
2268
  reuse it twice inside an `AddressPage` component displaying a Shipping Address and a Billing Address.
2249
2269
 
2250
- Glimmer GUI code:
2270
+ Glimmer GUI code in the frontend:
2251
2271
 
2252
2272
  ```ruby
2253
2273
  require 'glimmer-dsl-web'
@@ -2496,7 +2516,7 @@ Rails View code:
2496
2516
  </div>
2497
2517
  ```
2498
2518
 
2499
- Glimmer GUI code:
2519
+ Glimmer GUI code in the frontend (`app/assets/opal/address_form.rb`):
2500
2520
 
2501
2521
  ```ruby
2502
2522
  require 'glimmer-dsl-web'
@@ -2661,7 +2681,7 @@ Screenshot:
2661
2681
 
2662
2682
  #### Hello, Paragraph!
2663
2683
 
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>`
2684
+ 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 GUI 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
2685
 
2666
2686
  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.
2667
2687
 
@@ -2693,7 +2713,7 @@ it returns a `String` to enable code like this:
2693
2713
 
2694
2714
  In any case, below is a full example leveraging the Glimmer GUI DSL alternative approach when utilizing formatting elements underneath a paragraph.
2695
2715
 
2696
- Glimmer GUI code:
2716
+ Glimmer GUI code in the frontend:
2697
2717
 
2698
2718
  ```ruby
2699
2719
  require 'glimmer-dsl-web'
@@ -2754,7 +2774,7 @@ Screenshot:
2754
2774
 
2755
2775
  #### Hello, Input (Date/Time)!
2756
2776
 
2757
- Glimmer GUI code:
2777
+ Glimmer GUI code in the frontend:
2758
2778
 
2759
2779
  ```ruby
2760
2780
  require 'glimmer-dsl-web'
@@ -2859,7 +2879,7 @@ Screenshot:
2859
2879
 
2860
2880
  #### Button Counter
2861
2881
 
2862
- Glimmer GUI code demonstrating MVC + Glimmer Web Components (Views) + Data-Binding:
2882
+ Glimmer GUI code in the frontend demonstrating MVC + Glimmer Web Components (Views) + Data-Binding:
2863
2883
 
2864
2884
  ```ruby
2865
2885
  require 'glimmer-dsl-web'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.2
1
+ 0.2.3
@@ -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.3 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.3".freeze
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-01-13"
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) in building Isomorphic Ruby on Rails Applications. 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. 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
16
16
  s.email = "andy.am@gmail.com".freeze
17
17
  s.extra_rdoc_files = [
18
18
  "CHANGELOG.md",
@@ -54,10 +54,9 @@ Gem::Specification.new do |s|
54
54
  "lib/glimmer/dsl/web/general_element_expression.rb",
55
55
  "lib/glimmer/dsl/web/listener_expression.rb",
56
56
  "lib/glimmer/dsl/web/observe_expression.rb",
57
- "lib/glimmer/dsl/web/p_expression.rb",
58
57
  "lib/glimmer/dsl/web/property_expression.rb",
59
- "lib/glimmer/dsl/web/select_expression.rb",
60
58
  "lib/glimmer/dsl/web/shine_data_binding_expression.rb",
59
+ "lib/glimmer/dsl/web/span_expression.rb",
61
60
  "lib/glimmer/dsl/web/style_expression.rb",
62
61
  "lib/glimmer/helpers/glimmer_helper.rb",
63
62
  "lib/glimmer/util/proc_tracker.rb",
@@ -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
@@ -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
 
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.3
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-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer
@@ -235,12 +235,13 @@ description: Glimmer DSL for Web (Ruby in the Browser Web GUI Frontend Library)
235
235
  in his RubyConf 2022 keynote speech to replace JavaScript with Ruby. It aims at
236
236
  providing the simplest, most intuitive, most straight-forward, and most productive
237
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
239
- (One-Way) Data-Binding (using <=) and Bidirectional (Two-Way) Data-Binding (using
240
- <=>). Dynamic rendering (and re-rendering) of HTML content is also supported via
241
- 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.
238
+ and the Rails way (Convention over Configuration) in building Isomorphic Ruby on
239
+ Rails Applications. It supports both Unidirectional (One-Way) Data-Binding (using
240
+ <=) and Bidirectional (Two-Way) Data-Binding (using <=>). Dynamic rendering (and
241
+ re-rendering) of HTML content is also supported via Content Data-Binding. And, modular
242
+ design is supported with Glimmer Web Components. You can finally live in pure Rubyland
243
+ on the Web in both the frontend and backend with Glimmer DSL for Web! This library
244
+ relies on Opal Ruby.
244
245
  email: andy.am@gmail.com
245
246
  executables: []
246
247
  extensions: []
@@ -283,10 +284,9 @@ files:
283
284
  - lib/glimmer/dsl/web/general_element_expression.rb
284
285
  - lib/glimmer/dsl/web/listener_expression.rb
285
286
  - lib/glimmer/dsl/web/observe_expression.rb
286
- - lib/glimmer/dsl/web/p_expression.rb
287
287
  - lib/glimmer/dsl/web/property_expression.rb
288
- - lib/glimmer/dsl/web/select_expression.rb
289
288
  - lib/glimmer/dsl/web/shine_data_binding_expression.rb
289
+ - lib/glimmer/dsl/web/span_expression.rb
290
290
  - lib/glimmer/dsl/web/style_expression.rb
291
291
  - lib/glimmer/helpers/glimmer_helper.rb
292
292
  - lib/glimmer/util/proc_tracker.rb
@@ -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