glimmer-dsl-web 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64730435caff848fd16bfad099963c9c3d6298da78af51bb0bbcbd9c41ed5ca9
4
- data.tar.gz: 80cb8d417c40726210eab103ace178016c9595b2d123f931ab9dd2e6469e37ac
3
+ metadata.gz: a9250414d9d8804f3af1ddf5cc083ce9e06ff87e3a57e1686c1e9bb7cb1ee847
4
+ data.tar.gz: f9312dfb0e0a87a047b4b25216031587f965b70d8059a7de6d670105b2ce41ca
5
5
  SHA512:
6
- metadata.gz: 4964424f7ccc8b35257d5c28b28749f8ee9fcc0be889d498c17ff3a81faac173fc9d3ae2d1d4a0818a0af7685a3e88dd2885b4733cc213995a54c7d76a6f3443
7
- data.tar.gz: 4d9cb434aa3d62053f98351ec38c821198f2426cdc00503d6a0f2eefd402377a4158f80a504942e966df2c95f7b2ee1644bea199c1f63011fe0c719e9cb27628
6
+ metadata.gz: 05be5bd7202f612582819cf970eb8185e530c2dff83e90caae1e3d5b09ad18d1aad44cd622e5b1b6d17f5afd83eb61762af2a941ab7bc77ea39b409e81ce4e6c
7
+ data.tar.gz: 6a979d023e5faf0b78656ca332bf6593ea33ed224ab8f1f06490767466dd62861e6a560fec63be25352500e0e2fde92cfa9d31e47089a6f5a629f7546816c283
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.0.5
4
+
5
+ - Support `p` element as it was overriden by Ruby's `p` method.
6
+ - Update listener syntax to be the original HTML event name (e.g. `onclick`) without being underscored to keep the transition to the Glimmer GUI DSL simple (e.g. `onclick` not `on_click`)
7
+ - Wrap listener `event` argument with `Glimmer::Web::Event` object, which proxies calls to JS event when needed
8
+ - Rename Hello Button! Sample to Hello, Form! Sample: `require 'glimmer-dsl-web/samples/hello/hello_form'`
9
+ - Update Hello, Form! Sample to display browser native validation errors and have automatic focus support on the name field
10
+ - Event listeners do not call `prevent_default` by default anymore, leaving it to the consumer of the library to decide
11
+ - New Hello, Button! Sample (replacing older one): `require 'glimmer-dsl-web/samples/hello/hello_button'`
12
+
3
13
  ## 0.0.4
4
14
 
5
15
  - Support nesting attributes/properties under element (e.g. `input { value 'something'; dir 'rtl' }`)
data/README.md CHANGED
@@ -1,15 +1,11 @@
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.0.4 (Early Alpha)
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.0.5 (Early Alpha)
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
- 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, but it mainly differs from Glimmer DSL for Opal by adopting a DSL that follows web-like HTML syntax in Ruby (enabling transfer of HTML/CSS/JS skills) instead of adopting a desktop GUI DSL that is webified. Also, it will begin by supporting [Opal Ruby](https://opalrb.com/), but it 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.
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 frontend library in existence. 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
7
 
8
- Note that the library is an Early Alpha and its APIs might change frequently until hitting a minor release at least.
9
-
10
- ### You can finally live in pure Rubyland on the web!
11
-
12
- [Glimmer](https://github.com/AndyObtiva/glimmer) DSL for Web is an upcoming **pre-alpha** [gem](https://rubygems.org/gems/glimmer-dsl-web) that enables building web GUI in pure Ruby via [Opal](https://opalrb.com/) on [Rails](https://rubyonrails.org/) (and potentially [Ruby WASM](https://github.com/ruby/ruby.wasm) in the future).
8
+ 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.
13
9
 
14
10
  **Sample**
15
11
 
@@ -81,7 +77,43 @@ That produces the following under `<body></body>`:
81
77
 
82
78
  ![setup is working](/images/glimmer-dsl-web-setup-example-working.png)
83
79
 
84
- **Hello, Button! Sample**
80
+ **Hello, Button!**
81
+
82
+ 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`.
83
+
84
+ Glimmer GUI code:
85
+
86
+ ```ruby
87
+ require 'glimmer-dsl-web'
88
+
89
+ include Glimmer
90
+
91
+ Document.ready? do
92
+ div {
93
+ button('Greet') {
94
+ onclick do
95
+ $$.alert('Hello, Button!')
96
+ end
97
+ }
98
+ }.render
99
+ end
100
+ ```
101
+
102
+ That produces the following under `<body></body>`:
103
+
104
+ ```html
105
+ <div data-parent="body" class="element element-1">
106
+ <button class="element element-2">Greet</button>
107
+ </div>
108
+ ```
109
+
110
+ Screenshot:
111
+
112
+ ![Hello, Button!](/images/glimmer-dsl-web-samples-hello-hello-button.gif)
113
+
114
+ **Hello, Form!**
115
+
116
+ [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.
85
117
 
86
118
  Glimmer GUI code:
87
119
 
@@ -93,44 +125,50 @@ include Glimmer
93
125
  Document.ready? do
94
126
  div {
95
127
  h1('Contact Form')
128
+
96
129
  form {
97
- div(class: 'field-row') {
130
+ div {
98
131
  label('Name: ', for: 'name-field')
99
- @name_input = input(id: 'name-field', class: 'field', type: 'text', required: true)
132
+ @name_input = input(type: 'text', id: 'name-field', required: true, autofocus: true)
100
133
  }
101
- div(class: 'field-row') {
134
+
135
+ div {
102
136
  label('Email: ', for: 'email-field')
103
- @email_input = input(id: 'email-field', class: 'field', type: 'email', required: true)
137
+ @email_input = input(type: 'email', id: 'email-field', required: true)
104
138
  }
105
- button('Add Contact', class: 'submit-button') {
106
- on_click do
107
- if ([@name_input, @email_input].all? {|input| input.check_validity })
108
- @table.content {
109
- tr {
110
- td { @name_input.value }
111
- td { @email_input.value }
139
+
140
+ div {
141
+ input(type: 'submit', value: 'Add Contact') {
142
+ onclick do |event|
143
+ if ([@name_input, @email_input].all? {|input| input.check_validity })
144
+ # re-open table content and add row
145
+ @table.content {
146
+ tr {
147
+ td { @name_input.value }
148
+ td { @email_input.value }
149
+ }
112
150
  }
113
- }
114
- @email_input.value = @name_input.value = ''
115
- else
116
- error_messages = []
117
- error_messages << "Name is not valid! Make sure it is filled." if !@name_input.check_validity
118
- error_messages << "Email is not valid! Make sure it is filled and has a valid format." if !@email_input.check_validity
119
- $$.alert(error_messages.join("\n"))
151
+ @email_input.value = @name_input.value = ''
152
+ @name_input.focus
153
+ end
120
154
  end
121
- end
155
+ }
122
156
  }
123
157
  }
158
+
124
159
  h1('Contacts Table')
160
+
125
161
  @table = table {
126
162
  tr {
127
163
  th('Name')
128
164
  th('Email')
129
165
  }
166
+
130
167
  tr {
131
168
  td('John Doe')
132
169
  td('johndoe@example.com')
133
170
  }
171
+
134
172
  tr {
135
173
  td('Jane Doe')
136
174
  td('janedoe@example.com')
@@ -140,15 +178,11 @@ Document.ready? do
140
178
  # CSS Styles
141
179
  style {
142
180
  <<~CSS
143
- .field-row {
144
- margin: 10px 5px;
145
- }
146
- .field {
147
- margin-left: 5px;
181
+ input {
182
+ margin: 5px;
148
183
  }
149
- .submit-button {
150
- display: block;
151
- margin: 10px 5px;
184
+ input[type=submit] {
185
+ margin: 5px 0;
152
186
  }
153
187
  table {
154
188
  border:1px solid grey;
@@ -171,83 +205,66 @@ That produces the following under `<body></body>`:
171
205
  ```html
172
206
  <div data-parent="body" class="element element-1">
173
207
  <h1 class="element element-2">Contact Form</h1>
208
+
174
209
  <form class="element element-3">
175
- <div class="field-row element element-4">
210
+ <div class="element element-4">
176
211
  <label for="name-field" class="element element-5">Name: </label>
177
- <input id="name-field" class="field element element-6" type="text" required="true">
212
+ <input type="text" id="name-field" required="true" autofocus="true" class="element element-6">
178
213
  </div>
179
- <div class="field-row element element-7">
214
+
215
+ <div class="element element-7">
180
216
  <label for="email-field" class="element element-8">Email: </label>
181
- <input id="email-field" class="field element element-9" type="email" required="true">
217
+ <input type="email" id="email-field" required="true" class="element element-9">
218
+ </div>
219
+
220
+ <div class="element element-10">
221
+ <input type="submit" value="Add Contact" class="element element-11">
182
222
  </div>
183
- <button class="submit-button element element-10">Add Contact</button>
184
223
  </form>
185
- <h1 class="element element-11">Contacts Table</h1>
186
- <table class="element element-12">
187
- <tr class="element element-13">
188
- <th class="element element-14">Name</th>
189
- <th class="element element-15">Email</th>
224
+
225
+ <h1 class="element element-12">Contacts Table</h1>
226
+
227
+ <table class="element element-13">
228
+ <tr class="element element-14">
229
+ <th class="element element-15">Name</th>
230
+ <th class="element element-16">Email</th>
190
231
  </tr>
191
- <tr class="element element-16">
192
- <td class="element element-17">John Doe</td>
193
- <td class="element element-18">johndoe@example.com</td>
232
+
233
+ <tr class="element element-17">
234
+ <td class="element element-18">John Doe</td>
235
+ <td class="element element-19">johndoe@example.com</td>
194
236
  </tr>
195
- <tr class="element element-19">
196
- <td class="element element-20">Jane Doe</td>
197
- <td class="element element-21">janedoe@example.com</td>
237
+
238
+ <tr class="element element-20">
239
+ <td class="element element-21">Jane Doe</td>
240
+ <td class="element element-22">janedoe@example.com</td>
198
241
  </tr>
199
242
  </table>
200
- <style class="element element-22">.field-row {
201
- margin: 10px 5px;
202
- }
203
- .field {
204
- margin-left: 5px;
205
- }
206
- .submit-button {
207
- display: block;
208
- margin: 10px 5px;
209
- }
210
- table {
211
- border:1px solid grey;
212
- border-spacing: 0;
213
- }
214
- table tr td, table tr th {
215
- padding: 5px;
216
- }
217
- table tr:nth-child(even) {
218
- background: #ccc;
219
- }
243
+
244
+ <style class="element element-23">
245
+ input {
246
+ margin: 5px;
247
+ }
248
+ input[type=submit] {
249
+ margin: 5px 0;
250
+ }
251
+ table {
252
+ border:1px solid grey;
253
+ border-spacing: 0;
254
+ }
255
+ table tr td, table tr th {
256
+ padding: 5px;
257
+ }
258
+ table tr:nth-child(even) {
259
+ background: #ccc;
260
+ }
220
261
  </style>
221
262
  </div>
222
263
  ```
223
264
 
224
- Screenshots:
225
-
226
- ---
227
-
228
- ***Hello, Button!***
229
-
230
- ![Hello, Button!](/images/glimmer-dsl-web-samples-hello-hello-button.png)
231
-
232
- ---
233
-
234
- ***Hello, Button! Submitted Invalid Data***
235
-
236
- ![Hello, Button! Invalid Data](/images/glimmer-dsl-web-samples-hello-hello-button-invalid-data.png)
237
-
238
- ---
239
-
240
- ***Hello, Button! Filled Valid Name and Email***
241
-
242
- ![Hello, Button! Filled](/images/glimmer-dsl-web-samples-hello-hello-button-filled-name-and-email.png)
243
-
244
- ---
245
-
246
- ***Hello, Button! Added Contact***
247
-
248
- ![Hello, Button! Added Contact](/images/glimmer-dsl-web-samples-hello-hello-button-added-contact.png)
265
+ Screenshot:
249
266
 
250
- ---
267
+ ![Hello, Form!](/images/glimmer-dsl-web-samples-hello-hello-form.gif)
251
268
 
252
269
  **Button Counter Sample**
253
270
 
@@ -279,7 +296,7 @@ class HelloButton
279
296
 
280
297
  markup {
281
298
  # This will hook into element #app-container and then build HTML inside it using Ruby DSL code
282
- div(root_css_selector) {
299
+ div(parent: parent_selector) {
283
300
  text 'Button Counter'
284
301
 
285
302
  button {
@@ -288,7 +305,7 @@ class HelloButton
288
305
  # copied to button innerText (content) to display to the user
289
306
  inner_text <= [@counter, :count, on_read: ->(value) { "Click To Increment: #{value} " }]
290
307
 
291
- on_click {
308
+ onclick {
292
309
  @counter.increment!
293
310
  }
294
311
  }
@@ -349,7 +366,7 @@ Learn more about the differences between various [Glimmer](https://github.com/An
349
366
  - [Samples](#samples)
350
367
  - [Hello Samples](#hello-samples)
351
368
  - [Hello, World!](#hello-world)
352
- - [Hello, Button!](#hello-button)
369
+ - [Hello, Form!](#hello-form)
353
370
  - [Button Counter](#button-counter)
354
371
  - [Glimmer Process](#glimmer-process)
355
372
  - [Help](#help)
@@ -363,11 +380,12 @@ Learn more about the differences between various [Glimmer](https://github.com/An
363
380
 
364
381
  ## Prerequisites
365
382
 
383
+ [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.
384
+
366
385
  - Ruby 3.0 (newer Ruby versions are not supported at this time)
367
386
  - Rails 6-7: [https://github.com/rails/rails](https://github.com/rails/rails)
368
- - Opal 1.4.1 for Rails 6-7 or Opal 1.0.5 for Rails 5: [https://github.com/opal/opal](https://github.com/opal/opal)
369
- - Opal-Rails 2.0.2 for Rails 6-7 or Opal-Rails 1.1.2 for Rails 5: [https://github.com/opal/opal-rails](https://github.com/opal/opal-rails)
370
- - jQuery 3 (included): [https://code.jquery.com/](https://code.jquery.com/) (jQuery 3.6.0 is included in the [glimmer-dsl-web](https://rubygems.org/gems/glimmer-dsl-web) gem)
387
+ - Opal 1.4.1 for Rails 6-7: [https://github.com/opal/opal](https://github.com/opal/opal)
388
+ - Opal-Rails 2.0.2 for Rails 6-7: [https://github.com/opal/opal-rails](https://github.com/opal/opal-rails)
371
389
 
372
390
  ## Setup
373
391
 
@@ -398,7 +416,7 @@ gem 'opal', '1.4.1'
398
416
  gem 'opal-rails', '2.0.2'
399
417
  gem 'opal-async', '~> 1.4.0'
400
418
  gem 'opal-jquery', '~> 0.4.6'
401
- gem 'glimmer-dsl-web', '~> 0.0.4'
419
+ gem 'glimmer-dsl-web', '~> 0.0.5'
402
420
  gem 'glimmer-dsl-xml', '~> 1.3.1', require: false
403
421
  gem 'glimmer-dsl-css', '~> 1.2.1', require: false
404
422
  ```
@@ -543,7 +561,7 @@ gem 'opal', '1.4.1'
543
561
  gem 'opal-rails', '2.0.2'
544
562
  gem 'opal-async', '~> 1.4.0'
545
563
  gem 'opal-jquery', '~> 0.4.6'
546
- gem 'glimmer-dsl-web', '~> 0.0.4'
564
+ gem 'glimmer-dsl-web', '~> 0.0.5'
547
565
  gem 'glimmer-dsl-xml', '~> 1.3.1', require: false
548
566
  gem 'glimmer-dsl-css', '~> 1.2.1', require: false
549
567
  ```
@@ -669,19 +687,19 @@ Otherwise, if you still cannot setup successfully (even with the help of the sam
669
687
 
670
688
  Glimmer DSL for Web offers a GUI DSL for building HTML Web User Interfaces declaratively in Ruby.
671
689
 
672
- 1- Keywords (HTML Elements)
690
+ 1- **Keywords (HTML Elements)**
673
691
 
674
692
  You can declare any HTML element by simply using the lowercase underscored version of its name (Ruby convention for method names) like `div`, `span`, `form`, `input`, `button`, `table`, `tr`, `th`, and `td`.
675
693
 
676
694
  Under the hood, HTML element DSL keywords are invoked as Ruby methods.
677
695
 
678
- 2- Arguments (HTML Attributes + Text Content)
696
+ 2- **Arguments (HTML Attributes + Text Content)**
679
697
 
680
698
  You can set any HTML element attributes by passing as keyword arguments to element methods like `div(id: 'container', class: 'stack')` or `input(type: 'email', required: true)`
681
699
 
682
700
  Also, if the element has a little bit of text content that can fit in one line, it can be passed as the 1st argument like `label('Name: ', for: 'name_field')`, `button('Calculate', class: 'round-button')`, or `span('Mr')`
683
701
 
684
- 3- Content Block (Properties + Listeners + Nested Elements + Text Content)
702
+ 3- **Content Block (Properties + Listeners + Nested Elements + Text Content)**
685
703
 
686
704
  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.
687
705
 
@@ -693,11 +711,11 @@ input(type: 'text') {
693
711
  }
694
712
  ```
695
713
 
696
- You can nest HTML event listeners under an element by using a more friendly underscored version of listener properties (e.g. `onclick` becomes `on_click`):
714
+ You can nest HTML event listeners under an element by using the HTML event listener name (e.g. `onclick`, `onchange`, `onblur`):
697
715
 
698
716
  ```ruby
699
717
  button('Add') {
700
- on_click do
718
+ onclick do
701
719
  @model.add_selected_element
702
720
  end
703
721
  }
@@ -718,7 +736,7 @@ form {
718
736
  input(id: 'email-field', class: 'field', type: 'email', required: true)
719
737
  }
720
738
  button('Add Contact', class: 'submit-button') {
721
- on_click do
739
+ onclick do
722
740
  ...
723
741
  end
724
742
  }
@@ -728,17 +746,23 @@ form {
728
746
  You can nest text content underneath an element's Ruby block, like:
729
747
 
730
748
  ```ruby
731
- span(class: 'summary') {
749
+ p(class: 'summary') {
732
750
  'This text content is going into the body of the span element'
733
751
  }
734
752
  ```
735
753
 
754
+ 4- **Operations (Properties + Functions)**
755
+
756
+ 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`.
757
+
736
758
  ## Supported Glimmer DSL Keywords
737
759
 
738
760
  [All HTML elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Element).
739
761
 
740
762
  [All HTML attributes](https://www.w3schools.com/html/html_attributes.asp).
741
763
 
764
+ [All HTML events](https://www.w3schools.com/tags/ref_eventattributes.asp).
765
+
742
766
  ## Samples
743
767
 
744
768
  This external sample app contains all the samples mentioned below configured inside a Rails [Opal](https://opalrb.com/) app with all the prerequisites ready to go for convenience:
@@ -806,47 +830,85 @@ require 'glimmer-dsl-web'
806
830
 
807
831
  include Glimmer
808
832
 
833
+ Document.ready? do
834
+ div {
835
+ button('Greet') {
836
+ onclick do
837
+ $$.alert('Hello, Button!')
838
+ end
839
+ }
840
+ }.render
841
+ end
842
+ ```
843
+
844
+ That produces the following under `<body></body>`:
845
+
846
+ ```html
847
+ <div data-parent="body" class="element element-1">
848
+ <button class="element element-2">Greet</button>
849
+ </div>
850
+ ```
851
+
852
+ Screenshot:
853
+
854
+ ![Hello, Button!](/images/glimmer-dsl-web-samples-hello-hello-button.gif)
855
+
856
+ #### Hello, Form!
857
+
858
+ Glimmer GUI code:
859
+
860
+ ```ruby
861
+ require 'glimmer-dsl-web'
862
+
863
+ include Glimmer
864
+
809
865
  Document.ready? do
810
866
  div {
811
867
  h1('Contact Form')
868
+
812
869
  form {
813
- div(class: 'field-row') {
870
+ div {
814
871
  label('Name: ', for: 'name-field')
815
- @name_input = input(id: 'name-field', class: 'field', type: 'text', required: true)
872
+ @name_input = input(type: 'text', id: 'name-field', required: true, autofocus: true)
816
873
  }
817
- div(class: 'field-row') {
874
+
875
+ div {
818
876
  label('Email: ', for: 'email-field')
819
- @email_input = input(id: 'email-field', class: 'field', type: 'email', required: true)
877
+ @email_input = input(type: 'email', id: 'email-field', required: true)
820
878
  }
821
- button('Add Contact', class: 'submit-button') {
822
- on_click do
823
- if ([@name_input, @email_input].all? {|input| input.check_validity })
824
- @table.content {
825
- tr {
826
- td { @name_input.value }
827
- td { @email_input.value }
879
+
880
+ div {
881
+ input(type: 'submit', value: 'Add Contact') {
882
+ onclick do |event|
883
+ if ([@name_input, @email_input].all? {|input| input.check_validity })
884
+ # re-open table content and add row
885
+ @table.content {
886
+ tr {
887
+ td { @name_input.value }
888
+ td { @email_input.value }
889
+ }
828
890
  }
829
- }
830
- @email_input.value = @name_input.value = ''
831
- else
832
- error_messages = []
833
- error_messages << "Name is not valid! Make sure it is filled." if !@name_input.check_validity
834
- error_messages << "Email is not valid! Make sure it is filled and has a valid format." if !@email_input.check_validity
835
- $$.alert(error_messages.join("\n"))
891
+ @email_input.value = @name_input.value = ''
892
+ @name_input.focus
893
+ end
836
894
  end
837
- end
895
+ }
838
896
  }
839
897
  }
898
+
840
899
  h1('Contacts Table')
900
+
841
901
  @table = table {
842
902
  tr {
843
903
  th('Name')
844
904
  th('Email')
845
905
  }
906
+
846
907
  tr {
847
908
  td('John Doe')
848
909
  td('johndoe@example.com')
849
910
  }
911
+
850
912
  tr {
851
913
  td('Jane Doe')
852
914
  td('janedoe@example.com')
@@ -856,15 +918,11 @@ Document.ready? do
856
918
  # CSS Styles
857
919
  style {
858
920
  <<~CSS
859
- .field-row {
860
- margin: 10px 5px;
861
- }
862
- .field {
863
- margin-left: 5px;
921
+ input {
922
+ margin: 5px;
864
923
  }
865
- .submit-button {
866
- display: block;
867
- margin: 10px 5px;
924
+ input[type=submit] {
925
+ margin: 5px 0;
868
926
  }
869
927
  table {
870
928
  border:1px solid grey;
@@ -887,83 +945,66 @@ That produces the following under `<body></body>`:
887
945
  ```html
888
946
  <div data-parent="body" class="element element-1">
889
947
  <h1 class="element element-2">Contact Form</h1>
948
+
890
949
  <form class="element element-3">
891
- <div class="field-row element element-4">
950
+ <div class="element element-4">
892
951
  <label for="name-field" class="element element-5">Name: </label>
893
- <input id="name-field" class="field element element-6" type="text" required="true">
952
+ <input type="text" id="name-field" required="true" autofocus="true" class="element element-6">
894
953
  </div>
895
- <div class="field-row element element-7">
954
+
955
+ <div class="element element-7">
896
956
  <label for="email-field" class="element element-8">Email: </label>
897
- <input id="email-field" class="field element element-9" type="email" required="true">
957
+ <input type="email" id="email-field" required="true" class="element element-9">
958
+ </div>
959
+
960
+ <div class="element element-10">
961
+ <input type="submit" value="Add Contact" class="element element-11">
898
962
  </div>
899
- <button class="submit-button element element-10">Add Contact</button>
900
963
  </form>
901
- <h1 class="element element-11">Contacts Table</h1>
902
- <table class="element element-12">
903
- <tr class="element element-13">
904
- <th class="element element-14">Name</th>
905
- <th class="element element-15">Email</th>
964
+
965
+ <h1 class="element element-12">Contacts Table</h1>
966
+
967
+ <table class="element element-13">
968
+ <tr class="element element-14">
969
+ <th class="element element-15">Name</th>
970
+ <th class="element element-16">Email</th>
906
971
  </tr>
907
- <tr class="element element-16">
908
- <td class="element element-17">John Doe</td>
909
- <td class="element element-18">johndoe@example.com</td>
972
+
973
+ <tr class="element element-17">
974
+ <td class="element element-18">John Doe</td>
975
+ <td class="element element-19">johndoe@example.com</td>
910
976
  </tr>
911
- <tr class="element element-19">
912
- <td class="element element-20">Jane Doe</td>
913
- <td class="element element-21">janedoe@example.com</td>
977
+
978
+ <tr class="element element-20">
979
+ <td class="element element-21">Jane Doe</td>
980
+ <td class="element element-22">janedoe@example.com</td>
914
981
  </tr>
915
982
  </table>
916
- <style class="element element-22">.field-row {
917
- margin: 10px 5px;
918
- }
919
- .field {
920
- margin-left: 5px;
921
- }
922
- .submit-button {
923
- display: block;
924
- margin: 10px 5px;
925
- }
926
- table {
927
- border:1px solid grey;
928
- border-spacing: 0;
929
- }
930
- table tr td, table tr th {
931
- padding: 5px;
932
- }
933
- table tr:nth-child(even) {
934
- background: #ccc;
935
- }
983
+
984
+ <style class="element element-23">
985
+ input {
986
+ margin: 5px;
987
+ }
988
+ input[type=submit] {
989
+ margin: 5px 0;
990
+ }
991
+ table {
992
+ border:1px solid grey;
993
+ border-spacing: 0;
994
+ }
995
+ table tr td, table tr th {
996
+ padding: 5px;
997
+ }
998
+ table tr:nth-child(even) {
999
+ background: #ccc;
1000
+ }
936
1001
  </style>
937
1002
  </div>
938
1003
  ```
939
1004
 
940
- Screenshots:
941
-
942
- ---
943
-
944
- ***Hello, Button!***
945
-
946
- ![Hello, Button!](/images/glimmer-dsl-web-samples-hello-hello-button.png)
947
-
948
- ---
949
-
950
- ***Hello, Button! Submitted Invalid Data***
951
-
952
- ![Hello, Button! Invalid Data](/images/glimmer-dsl-web-samples-hello-hello-button-invalid-data.png)
953
-
954
- ---
955
-
956
- ***Hello, Button! Filled Valid Name and Email***
957
-
958
- ![Hello, Button! Filled](/images/glimmer-dsl-web-samples-hello-hello-button-filled-name-and-email.png)
959
-
960
- ---
961
-
962
- ***Hello, Button! Added Contact***
963
-
964
- ![Hello, Button! Added Contact](/images/glimmer-dsl-web-samples-hello-hello-button-added-contact.png)
1005
+ Screenshot:
965
1006
 
966
- ---
1007
+ ![Hello, Form!](/images/glimmer-dsl-web-samples-hello-hello-form.gif)
967
1008
 
968
1009
  #### Button Counter
969
1010
 
@@ -995,7 +1036,7 @@ class HelloButton
995
1036
 
996
1037
  markup {
997
1038
  # This will hook into element #app-container and then build HTML inside it using Ruby DSL code
998
- div(root_css_selector) {
1039
+ div(parent: parent_selector) {
999
1040
  text 'Button Counter'
1000
1041
 
1001
1042
  button {
@@ -1004,7 +1045,7 @@ class HelloButton
1004
1045
  # copied to button innerText (content) to display to the user
1005
1046
  inner_text <= [@counter, :count, on_read: ->(value) { "Click To Increment: #{value} " }]
1006
1047
 
1007
- on_click {
1048
+ onclick {
1008
1049
  @counter.increment!
1009
1050
  }
1010
1051
  }
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.0.5
@@ -2,11 +2,11 @@
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.0.4 ruby lib
5
+ # stub: glimmer-dsl-web 0.0.5 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "glimmer-dsl-web".freeze
9
- s.version = "0.0.4".freeze
9
+ s.version = "0.0.5".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]
@@ -31,18 +31,20 @@ Gem::Specification.new do |s|
31
31
  "lib/glimmer-dsl-web/ext/date.rb",
32
32
  "lib/glimmer-dsl-web/ext/exception.rb",
33
33
  "lib/glimmer-dsl-web/samples/hello/hello_button.rb",
34
+ "lib/glimmer-dsl-web/samples/hello/hello_form.rb",
34
35
  "lib/glimmer-dsl-web/samples/hello/hello_world.rb",
35
36
  "lib/glimmer-dsl-web/vendor/jquery.js",
36
37
  "lib/glimmer/config/opal_logger.rb",
37
38
  "lib/glimmer/data_binding/element_binding.rb",
38
- "lib/glimmer/data_binding/observable_element.rb",
39
39
  "lib/glimmer/dsl/web/dsl.rb",
40
40
  "lib/glimmer/dsl/web/element_expression.rb",
41
41
  "lib/glimmer/dsl/web/listener_expression.rb",
42
+ "lib/glimmer/dsl/web/p_expression.rb",
42
43
  "lib/glimmer/dsl/web/property_expression.rb",
43
44
  "lib/glimmer/util/proc_tracker.rb",
44
45
  "lib/glimmer/web.rb",
45
46
  "lib/glimmer/web/element_proxy.rb",
47
+ "lib/glimmer/web/event_proxy.rb",
46
48
  "lib/glimmer/web/listener_proxy.rb",
47
49
  "lib/glimmer/web/property_owner.rb"
48
50
  ]
@@ -3,6 +3,7 @@ require 'glimmer/dsl/engine'
3
3
  require 'glimmer/dsl/web/element_expression'
4
4
  require 'glimmer/dsl/web/listener_expression'
5
5
  require 'glimmer/dsl/web/property_expression'
6
+ require 'glimmer/dsl/web/p_expression'
6
7
 
7
8
  module Glimmer
8
9
  module DSL
@@ -11,7 +11,7 @@ module Glimmer
11
11
  def can_interpret?(parent, keyword, *args, &block)
12
12
  # TODO automatically pass parent option as element if not passed instead of rejecting elements without a paraent nor root
13
13
  # TODO raise a proper error if root is an element that is not found (maybe do this in model)
14
- !keyword.to_s.start_with?('on_')
14
+ !keyword.to_s.start_with?('on')
15
15
  end
16
16
 
17
17
  def interpret(parent, keyword, *args, &block)
@@ -0,0 +1,31 @@
1
+ require 'glimmer/dsl/static_expression'
2
+ require 'glimmer/dsl/parent_expression'
3
+
4
+ require 'glimmer/web/element_proxy'
5
+
6
+ module Glimmer
7
+ module DSL
8
+ module Web
9
+ class PExpression < StaticExpression
10
+ include ParentExpression
11
+
12
+ def interpret(parent, keyword, *args, &block)
13
+ Glimmer::Web::ElementProxy.for(keyword, parent, args, block)
14
+ end
15
+
16
+ def add_content(parent, keyword, *args, &block)
17
+ if parent.rendered? || parent.skip_content_on_render_blocks?
18
+ return_value = super(parent, keyword, *args, &block)
19
+ if return_value.is_a?(String) && parent.dom_element.text.to_s.empty?
20
+ parent.add_text_content(return_value)
21
+ end
22
+ parent.post_add_content
23
+ return_value
24
+ else
25
+ parent.add_content_on_render(&block)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -74,7 +74,7 @@ module Glimmer
74
74
 
75
75
  GLIMMER_ATTRIBUTES = [:parent]
76
76
 
77
- attr_reader :keyword, :parent, :args, :options, :children, :enabled, :foreground, :background, :focus, :removed?, :rendered
77
+ attr_reader :keyword, :parent, :args, :options, :children, :enabled, :foreground, :background, :removed?, :rendered
78
78
  alias rendered? rendered
79
79
 
80
80
  def initialize(keyword, parent, args, block)
@@ -176,16 +176,6 @@ module Glimmer
176
176
  dom_element.css('background-color', background.to_css) unless background.nil?
177
177
  end
178
178
 
179
- def focus=(value)
180
- @focus = value
181
- dom_element.focus # TODO consider if a delay or async_exec is needed here
182
- end
183
-
184
- def set_focus
185
- self.focus = true
186
- end
187
- alias setFocus set_focus
188
-
189
179
  def parent_selector
190
180
  @parent&.selector
191
181
  end
@@ -226,7 +216,7 @@ module Glimmer
226
216
  end
227
217
  end
228
218
  end
229
- alias redraw render
219
+ alias rerender render
230
220
 
231
221
  def attach(the_parent_dom_element)
232
222
  the_parent_dom_element.append(@dom)
@@ -743,7 +733,7 @@ module Glimmer
743
733
  def can_handle_observation_request?(keyword)
744
734
  # TODO sort this out for Opal
745
735
  keyword = keyword.to_s
746
- keyword.start_with?('on_')
736
+ keyword.start_with?('on')
747
737
  # if keyword.start_with?('on_swt_')
748
738
  # constant_name = keyword.sub(/^on_swt_/, '')
749
739
  # SWTProxy.has_constant?(constant_name)
@@ -765,10 +755,10 @@ module Glimmer
765
755
 
766
756
  def handle_javascript_observation_request(keyword, original_event_listener)
767
757
  listener = ListenerProxy.new(
768
- element_proxy: self,
758
+ element: self,
769
759
  selector: selector,
770
760
  dom_element: dom_element,
771
- event: keyword.sub(/^on_/, ''),
761
+ event_attribute: keyword,
772
762
  listener: original_event_listener,
773
763
  original_event_listener: original_event_listener
774
764
  )
@@ -827,6 +817,7 @@ module Glimmer
827
817
  end
828
818
 
829
819
  def respond_to_missing?(method_name, include_private = false)
820
+ # TODO consider doing more correct checking of availability of properties/methods using native `` ticks
830
821
  property_name = property_name_for(method_name)
831
822
  super(method_name, include_private) ||
832
823
  (dom_element && dom_element.length > 0 && Native.call(dom_element, '0').respond_to?(method_name.to_s.camelcase, include_private)) ||
@@ -836,6 +827,7 @@ module Glimmer
836
827
  end
837
828
 
838
829
  def method_missing(method_name, *args, &block)
830
+ # TODO consider doing more correct checking of availability of properties/methods using native `` ticks
839
831
  property_name = property_name_for(method_name)
840
832
  if method_name.to_s.start_with?('on_')
841
833
  handle_observation_request(method_name, block)
@@ -0,0 +1,59 @@
1
+ # Copyright (c) 2023 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ module Glimmer
23
+ module Web
24
+ class EventProxy
25
+ attr_reader :js_event, :listener
26
+
27
+ def initialize(js_event:, listener:)
28
+ @js_event = js_event
29
+ @listener = listener
30
+ end
31
+
32
+ def element = listener.element
33
+ def event_name = listener.event_name
34
+ def event_attribute = listener.event_attribute
35
+
36
+ def original_event
37
+ Native(`#{js_event.to_n}.originalEvent`)
38
+ end
39
+
40
+ def respond_to_missing?(method_name, include_private = false)
41
+ property_name = method_name.to_s.camelcase
42
+ super(method_name, include_private) ||
43
+ js_event.respond_to?(method_name, include_private) ||
44
+ `#{property_name} in #{original_event.to_n}`
45
+ end
46
+
47
+ def method_missing(method_name, *args, &block)
48
+ property_name = method_name.to_s.camelcase
49
+ if js_event.respond_to?(method_name, true)
50
+ js_event.send(method_name, *args, &block)
51
+ elsif `#{property_name} in #{original_event.to_n}`
52
+ original_event[property_name]
53
+ else
54
+ super(method_name, *args, &block)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,36 +1,58 @@
1
+ # Copyright (c) 2023 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'glimmer/web/event_proxy'
23
+
1
24
  module Glimmer
2
25
  module Web
3
26
  class ListenerProxy
4
- attr_reader :element_proxy, :event, :dom_element, :selector, :listener, :original_event_listener
27
+ attr_reader :element, :event_attribute, :event_name, :dom_element, :selector, :listener, :js_listener, :original_event_listener
5
28
 
6
- def initialize(element_proxy:, event:, dom_element:, selector:, listener:)
7
- @element_proxy = element_proxy
8
- @event = event
29
+ def initialize(element:, event_attribute:, dom_element:, selector:, listener:)
30
+ @element = element
31
+ @event_attribute = event_attribute
32
+ @event_name = event_attribute.sub(/^on/, '')
9
33
  @dom_element = dom_element
10
34
  @selector = selector
11
35
  @listener = listener
12
- @js_listener = lambda do |event|
13
- event.prevent
14
- event.prevent_default
15
- event.stop_propagation
16
- event.stop_immediate_propagation
36
+ @js_listener = lambda do |js_event|
17
37
  # TODO wrap event with a Ruby Event object before passing to listener
18
- listener.call(event)
19
- false
38
+ event = EventProxy.new(js_event: js_event, listener: self)
39
+ result = listener.call(event)
40
+ result = true if result.nil?
41
+ result
20
42
  end
21
43
  @original_event_listener = original_event_listener
22
44
  end
23
45
 
24
46
  def register
25
- @dom_element.on(@event, &@js_listener)
47
+ @dom_element.on(@event_name, &@js_listener)
26
48
  end
27
49
  alias observe register
28
50
  alias reregister register
29
51
 
30
52
  def unregister
31
53
  # TODO contribute fix to opal to allow passing observer with & to off with selector not specified as nil
32
- @dom_element.off(@event, @js_listener)
33
- @element_proxy.listeners_for(@event).delete(self)
54
+ @dom_element.off(@event_name, @js_listener)
55
+ @element.listeners_for(@event_attribute).delete(self)
34
56
  end
35
57
  alias unobserve unregister
36
58
  alias deregister unregister
@@ -25,75 +25,10 @@ include Glimmer
25
25
 
26
26
  Document.ready? do
27
27
  div {
28
- h1('Contact Form')
29
- form {
30
- div(class: 'field-row') {
31
- label('Name: ', for: 'name-field')
32
- @name_input = input(id: 'name-field', class: 'field', type: 'text', required: true)
33
- }
34
- div(class: 'field-row') {
35
- label('Email: ', for: 'email-field')
36
- @email_input = input(id: 'email-field', class: 'field', type: 'email', required: true)
37
- }
38
- button('Add Contact', class: 'submit-button') {
39
- on_click do
40
- if ([@name_input, @email_input].all? {|input| input.check_validity })
41
- @table.content {
42
- tr {
43
- td { @name_input.value }
44
- td { @email_input.value }
45
- }
46
- }
47
- @email_input.value = @name_input.value = ''
48
- else
49
- error_messages = []
50
- error_messages << "Name is not valid! Make sure it is filled." if !@name_input.check_validity
51
- error_messages << "Email is not valid! Make sure it is filled and has a valid format." if !@email_input.check_validity
52
- $$.alert(error_messages.join("\n"))
53
- end
54
- end
55
- }
56
- }
57
- h1('Contacts Table')
58
- @table = table {
59
- tr {
60
- th('Name')
61
- th('Email')
62
- }
63
- tr {
64
- td('John Doe')
65
- td('johndoe@example.com')
66
- }
67
- tr {
68
- td('Jane Doe')
69
- td('janedoe@example.com')
70
- }
71
- }
72
-
73
- # CSS Styles
74
- style {
75
- <<~CSS
76
- .field-row {
77
- margin: 10px 5px;
78
- }
79
- .field {
80
- margin-left: 5px;
81
- }
82
- .submit-button {
83
- display: block;
84
- margin: 10px 5px;
85
- }
86
- table {
87
- border:1px solid grey;
88
- border-spacing: 0;
89
- }
90
- table tr td, table tr th {
91
- padding: 5px;
92
- }
93
- table tr:nth-child(even) {
94
- background: #ccc;
95
- }
96
- CSS
28
+ button('Greet') {
29
+ onclick do
30
+ $$.alert('Hello, Button!')
31
+ end
97
32
  }
98
33
  }.render
99
34
  end
@@ -0,0 +1,102 @@
1
+ # Copyright (c) 2023 Andy Maleh
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ require 'glimmer-dsl-web'
23
+
24
+ include Glimmer
25
+
26
+ Document.ready? do
27
+ div {
28
+ h1('Contact Form')
29
+
30
+ form {
31
+ div {
32
+ label('Name: ', for: 'name-field')
33
+ @name_input = input(type: 'text', id: 'name-field', required: true, autofocus: true)
34
+ }
35
+
36
+ div {
37
+ label('Email: ', for: 'email-field')
38
+ @email_input = input(type: 'email', id: 'email-field', required: true)
39
+ }
40
+
41
+ div {
42
+ input(type: 'submit', value: 'Add Contact') {
43
+ onclick do |event|
44
+ if ([@name_input, @email_input].all? {|input| input.check_validity })
45
+ event.prevent_default
46
+ # re-open table content and add row
47
+ @table.content {
48
+ tr {
49
+ td { @name_input.value }
50
+ td { @email_input.value }
51
+ }
52
+ }
53
+ @email_input.value = @name_input.value = ''
54
+ @name_input.focus
55
+ end
56
+ end
57
+ }
58
+ }
59
+ }
60
+
61
+ h1('Contacts Table')
62
+
63
+ @table = table {
64
+ tr {
65
+ th('Name')
66
+ th('Email')
67
+ }
68
+
69
+ tr {
70
+ td('John Doe')
71
+ td('johndoe@example.com')
72
+ }
73
+
74
+ tr {
75
+ td('Jane Doe')
76
+ td('janedoe@example.com')
77
+ }
78
+ }
79
+
80
+ # CSS Styles
81
+ style {
82
+ <<~CSS
83
+ input {
84
+ margin: 5px;
85
+ }
86
+ input[type=submit] {
87
+ margin: 5px 0;
88
+ }
89
+ table {
90
+ border:1px solid grey;
91
+ border-spacing: 0;
92
+ }
93
+ table tr td, table tr th {
94
+ padding: 5px;
95
+ }
96
+ table tr:nth-child(even) {
97
+ background: #ccc;
98
+ }
99
+ CSS
100
+ }
101
+ }.render
102
+ end
@@ -76,12 +76,7 @@ if RUBY_ENGINE == 'opal'
76
76
  require 'glimmer-dsl-xml'
77
77
  require 'glimmer-dsl-css'
78
78
 
79
- # TODO double check if alias native calls below have been added to jQuery-Opal (remove if so)
80
- Element.alias_native :replace_with, :replaceWith
81
- Element.alias_native :select
82
- # Element.alias_native :dialog
83
-
84
- Glimmer::Config.loop_max_count = 150 # TODO disable
79
+ Glimmer::Config.loop_max_count = 150 # TODO consider disabling if preferred
85
80
 
86
81
  original_logger_level = Glimmer::Config.logger.level
87
82
  Glimmer::Config.logger = Glimmer::Config::OpalLogger.new(STDOUT)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-dsl-web
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
@@ -259,18 +259,20 @@ files:
259
259
  - lib/glimmer-dsl-web/ext/date.rb
260
260
  - lib/glimmer-dsl-web/ext/exception.rb
261
261
  - lib/glimmer-dsl-web/samples/hello/hello_button.rb
262
+ - lib/glimmer-dsl-web/samples/hello/hello_form.rb
262
263
  - lib/glimmer-dsl-web/samples/hello/hello_world.rb
263
264
  - lib/glimmer-dsl-web/vendor/jquery.js
264
265
  - lib/glimmer/config/opal_logger.rb
265
266
  - lib/glimmer/data_binding/element_binding.rb
266
- - lib/glimmer/data_binding/observable_element.rb
267
267
  - lib/glimmer/dsl/web/dsl.rb
268
268
  - lib/glimmer/dsl/web/element_expression.rb
269
269
  - lib/glimmer/dsl/web/listener_expression.rb
270
+ - lib/glimmer/dsl/web/p_expression.rb
270
271
  - lib/glimmer/dsl/web/property_expression.rb
271
272
  - lib/glimmer/util/proc_tracker.rb
272
273
  - lib/glimmer/web.rb
273
274
  - lib/glimmer/web/element_proxy.rb
275
+ - lib/glimmer/web/event_proxy.rb
274
276
  - lib/glimmer/web/listener_proxy.rb
275
277
  - lib/glimmer/web/property_owner.rb
276
278
  homepage: http://github.com/AndyObtiva/glimmer-dsl-web
@@ -1,14 +0,0 @@
1
- module Glimmer
2
- module DataBinding
3
- module ObservableElement
4
- def method_missing(method, *args, &block)
5
- method_name = method.to_s
6
- if method_name.start_with?('on_')
7
- handle_observation_request(method_name, block)
8
- else
9
- super
10
- end
11
- end
12
- end
13
- end
14
- end