glimmer-dsl-web 0.0.11 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +235 -30
- data/VERSION +1 -1
- data/glimmer-dsl-web.gemspec +7 -4
- data/lib/glimmer/dsl/web/dsl.rb +2 -0
- data/lib/glimmer/dsl/web/formatting_element_expression.rb +19 -0
- data/lib/glimmer/web/component.rb +16 -4
- data/lib/glimmer/web/element_proxy.rb +21 -4
- data/lib/glimmer/web/event_proxy.rb +2 -0
- data/lib/glimmer/web/formatting_element_proxy.rb +56 -0
- data/lib/glimmer-dsl-web/samples/hello/hello_button.rb +1 -1
- data/lib/glimmer-dsl-web/samples/hello/hello_content_data_binding.rb +1 -1
- data/lib/glimmer-dsl-web/samples/hello/hello_data_binding.rb +1 -1
- data/lib/glimmer-dsl-web/samples/hello/hello_form.rb +1 -1
- data/lib/glimmer-dsl-web/samples/hello/hello_input_date_time.rb +1 -1
- data/lib/glimmer-dsl-web/samples/hello/hello_observer.rb +7 -3
- data/lib/glimmer-dsl-web/samples/hello/hello_paragraph.rb +67 -0
- data/lib/glimmer-dsl-web/samples/hello/hello_world.rb +1 -1
- metadata +16 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c9bd6a7f085751de551a8eada611f25b6462c32f31019ebc31e296a98a7dbe7
|
4
|
+
data.tar.gz: cde631c346fddf15d48c52b85643f4f436761b059ccca0a8909cca56fdc7676e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 036cbe077a6378e6fb18cf10060074b4a071b20f4293960ded842458069c4dfb5bc041eb909f0b7b3cfbb809f73a41605f2b97f101b338f1ee616e52f00445c3
|
7
|
+
data.tar.gz: 4441339edfaf2724324e4aa30c19b2afc7e0e9d673add6130882e1c3220e278a1be1d21be126bf9b8aaa7568c62a0c59ecbce9ca2d1103183263ae17deb2d15e
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.1.0
|
4
|
+
|
5
|
+
- Update rendering system to render HTML elements immediately instead of waiting for complete components to be rendered all at once.
|
6
|
+
- Support `render: false` option in any element or component to avoid rendering when building the elements/components (including a Component#create alternative to Component#render that defers rendering if needed).
|
7
|
+
- Fix `Glimmer::Web::Component` `after_render` hook by ensuring it only fires after the component markup has been rendered
|
8
|
+
|
9
|
+
## 0.0.12
|
10
|
+
|
11
|
+
- Treat HTML text formatting elements differently (e.g. `b`, `i`, `strong`, `em`, `sub`, `sup`, `del`, `ins`, `small`, `mark`) by not appending to their parent content, yet having them generate a String with `to_s` that can be embedded in a `String` that is the text content of another normal element like `p` or `div`.
|
12
|
+
- Treat `span` as a special text formatting element if included inside a `p` and as a normal element outside a `p`.
|
13
|
+
- Hello, Paragraph! Sample: `require 'glimmer-dsl-web/samples/hello/hello_paragraph'`
|
14
|
+
|
3
15
|
## 0.0.11
|
4
16
|
|
5
17
|
- Support element custom event listener: `on_remove`
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Web 0.0
|
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.1.0 (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)
|
@@ -17,7 +17,7 @@ include Glimmer
|
|
17
17
|
Document.ready? do
|
18
18
|
div {
|
19
19
|
'Hello, World!'
|
20
|
-
}
|
20
|
+
}
|
21
21
|
end
|
22
22
|
```
|
23
23
|
|
@@ -49,7 +49,7 @@ Document.ready? do
|
|
49
49
|
$$.alert('Hello, Button!')
|
50
50
|
end
|
51
51
|
}
|
52
|
-
}
|
52
|
+
}
|
53
53
|
end
|
54
54
|
```
|
55
55
|
|
@@ -150,7 +150,7 @@ Document.ready? do
|
|
150
150
|
}
|
151
151
|
CSS
|
152
152
|
}
|
153
|
-
}
|
153
|
+
}
|
154
154
|
end
|
155
155
|
```
|
156
156
|
|
@@ -245,7 +245,11 @@ class HelloObserver
|
|
245
245
|
end
|
246
246
|
|
247
247
|
after_render do
|
248
|
-
|
248
|
+
@number_input.value = @number_holder.number
|
249
|
+
@range_input.value = @number_holder.number
|
250
|
+
# Observe Model attribute @number_holder.number for changes and update View
|
251
|
+
# Observer is automatically cleaned up if remove method is called on rendered HelloObserver
|
252
|
+
# or its top-level element
|
249
253
|
observe(@number_holder, :number) do
|
250
254
|
number_string = @number_holder.number.to_s
|
251
255
|
@number_input.value = number_string unless @number_input.value == number_string
|
@@ -260,7 +264,7 @@ class HelloObserver
|
|
260
264
|
markup {
|
261
265
|
div {
|
262
266
|
div {
|
263
|
-
@number_input = input(type: 'number',
|
267
|
+
@number_input = input(type: 'number', min: 0, max: 100) {
|
264
268
|
# oninput listener updates Model attribute @number_holder.number
|
265
269
|
oninput do
|
266
270
|
@number_holder.number = @number_input.value.to_i
|
@@ -274,7 +278,7 @@ class HelloObserver
|
|
274
278
|
}
|
275
279
|
}
|
276
280
|
div {
|
277
|
-
@range_input = input(type: 'range',
|
281
|
+
@range_input = input(type: 'range', min: 0, max: 100) {
|
278
282
|
# oninput listener updates Model attribute @number_holder.number
|
279
283
|
oninput do
|
280
284
|
@number_holder.number = @range_input.value.to_i
|
@@ -409,7 +413,7 @@ Document.ready? do
|
|
409
413
|
computed_by: @address.members + ['state_code'],
|
410
414
|
]
|
411
415
|
}
|
412
|
-
}
|
416
|
+
}
|
413
417
|
end
|
414
418
|
```
|
415
419
|
|
@@ -544,7 +548,7 @@ Document.ready? do
|
|
544
548
|
end
|
545
549
|
end
|
546
550
|
}
|
547
|
-
}
|
551
|
+
}
|
548
552
|
end
|
549
553
|
```
|
550
554
|
|
@@ -978,7 +982,100 @@ Screenshot:
|
|
978
982
|
|
979
983
|
![Hello, glimmer_component Rails Helper!](/images/glimmer-dsl-web-samples-hello-hello-component.png)
|
980
984
|
|
981
|
-
|
985
|
+
**Hello, Paragraph!**
|
986
|
+
|
987
|
+
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>`
|
988
|
+
|
989
|
+
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.
|
990
|
+
|
991
|
+
This enables writing code like:
|
992
|
+
|
993
|
+
`p {"#{strong('Yesterday, ')}Robert suggested adding a new #{em('feature')} to our software product.#{br}}`
|
994
|
+
|
995
|
+
That is close to how it is written in HTML, albeit briefer in Ruby:
|
996
|
+
|
997
|
+
`<p><strong>Yesterday, </strong>Robert suggested adding a new <em>feature</em> to our software product.<br></p>`
|
998
|
+
|
999
|
+
Formatting elements just like regular elements can accept text content as their first argument or as their block return value. So, the code above could equally be written as follows:
|
1000
|
+
|
1001
|
+
`p {"#{strong{'Yesterday, '}}Robert suggested adding a new #{em{'feature'}} to our software product.#{br}}`
|
1002
|
+
|
1003
|
+
This enables seggregating formatting element attributes if desired, as in this example:
|
1004
|
+
|
1005
|
+
`p {"#{strong(class: 'very-string'){'Yesterday, '}}Robert suggested adding a new #{em(class: 'very-emphasized'){'feature'}} to our software product.#{br}}`
|
1006
|
+
|
1007
|
+
Another way of writing the same code is to pass the text content as the first argument, before attributes:
|
1008
|
+
|
1009
|
+
|
1010
|
+
`p {"#{strong('Yesterday, ', class: 'very-string')}Robert suggested adding a new #{em('feature', class: 'very-emphasized')} to our software product.#{br}}`
|
1011
|
+
|
1012
|
+
One last bit of info to keep in mind is that `<span>` generally generates a normal element, except when used inside a `<p>`'s content block, in which case it is assumed to be used for formatting, so
|
1013
|
+
it returns a `String` to enable code like this:
|
1014
|
+
|
1015
|
+
`p {"#{span('Yesterday, ', style: 'text-decoration: underline;')}Robert suggested adding a new #{em('feature', class: 'very-emphasized')} to our software product.#{br}}`
|
1016
|
+
|
1017
|
+
In any case, below is a full example leveraging the Glimmer GUI DSL alternative approach when utilizing formatting elements underneath a paragraph.
|
1018
|
+
|
1019
|
+
Glimmer GUI code:
|
1020
|
+
|
1021
|
+
```ruby
|
1022
|
+
require 'glimmer-dsl-web'
|
1023
|
+
|
1024
|
+
class HelloParagraph
|
1025
|
+
include Glimmer::Web::Component
|
1026
|
+
|
1027
|
+
markup {
|
1028
|
+
div {
|
1029
|
+
h1(class: 'title') {
|
1030
|
+
'Flying Cars Become 100% Safe with AI Powered Balance!'
|
1031
|
+
}
|
1032
|
+
|
1033
|
+
p(class: 'intro') {"
|
1034
|
+
In the early 2030's, #{em('flying cars')} became affordable after their prices dropped
|
1035
|
+
below #{small(del('$100,000'))}#{ins('$80,000')} as a result of the innovations of #{strong('Travel-X')}. Still, that did not
|
1036
|
+
make #{em('flying cars')} any popular due to the extreme difficulty in piloting such flying vehicles for the average
|
1037
|
+
person, making it very tough to pass the tests for getting a piloting license given the learning curve.
|
1038
|
+
"}
|
1039
|
+
|
1040
|
+
p {"
|
1041
|
+
That said, #{b('Travel-X')} has recently come up with a new feature for their flagship #{i('flying car')},
|
1042
|
+
the Ptero#{sub(1)}#{sup('TM')}, which relies on AI#{sub(2)} to automatically balance the flying cars in mid-air,
|
1043
|
+
thus significantly facilitating their piloting by the average consumer.
|
1044
|
+
"}
|
1045
|
+
|
1046
|
+
p(class: 'conclusion') {"
|
1047
|
+
That Ptero#{sup('TM')} will be so stable and well balanced while flying that the consumer will be able to drive
|
1048
|
+
as if it is a plain old car, with the only difference being vertical elevation, the control of which will be handled
|
1049
|
+
automatically by AI. The Ptero#{sup('TM')} will debut for #{span(style: 'text-decoration: underline dashed;'){'$79,000'}}.
|
1050
|
+
"}
|
1051
|
+
|
1052
|
+
h2(class: 'legend-title') {
|
1053
|
+
mark('Legend:')
|
1054
|
+
}
|
1055
|
+
|
1056
|
+
p(class: 'legend') {"
|
1057
|
+
#{strong("1- Ptero:")} Pterosaur is flying dinosaur species#{br}
|
1058
|
+
#{strong("2- AI:")} Artificial Intelligence#{br}
|
1059
|
+
"}
|
1060
|
+
|
1061
|
+
}
|
1062
|
+
}
|
1063
|
+
end
|
1064
|
+
|
1065
|
+
Document.ready? do
|
1066
|
+
HelloParagraph.render
|
1067
|
+
end
|
1068
|
+
```
|
1069
|
+
|
1070
|
+
Screenshot:
|
1071
|
+
|
1072
|
+
--
|
1073
|
+
|
1074
|
+
![Hello, Paragraph!](/images/glimmer-dsl-web-samples-hello-hello-paragraph.png)
|
1075
|
+
|
1076
|
+
--
|
1077
|
+
|
1078
|
+
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.
|
982
1079
|
|
983
1080
|
Learn more about the differences between various [Glimmer](https://github.com/AndyObtiva/glimmer) DSLs by looking at:
|
984
1081
|
|
@@ -986,9 +1083,7 @@ Learn more about the differences between various [Glimmer](https://github.com/An
|
|
986
1083
|
|
987
1084
|
## Table of Contents
|
988
1085
|
|
989
|
-
- [Glimmer DSL for Web](
|
990
|
-
- [Principles](#principles)
|
991
|
-
- [Background](#background)
|
1086
|
+
- [Glimmer DSL for Web](#)
|
992
1087
|
- [Prerequisites](#prerequisites)
|
993
1088
|
- [Setup](#setup)
|
994
1089
|
- [Usage](#usage)
|
@@ -1004,8 +1099,11 @@ Learn more about the differences between various [Glimmer](https://github.com/An
|
|
1004
1099
|
- [Hello, Content Data-Binding!](#hello-content-data-binding)
|
1005
1100
|
- [Hello, Component!](#hello-content-data-binding)
|
1006
1101
|
- [Hello, glimmer_component Rails Helper!](#hello-glimmer_component-rails-helper)
|
1102
|
+
- [Hello, Paragraph!](#hello-paragraph)
|
1007
1103
|
- [Hello, Input (Date/Time)!](#hello-input-datetime)
|
1008
1104
|
- [Button Counter](#button-counter)
|
1105
|
+
- [Design Principles](#design-principles)
|
1106
|
+
- [Supporting Libraries](#supporting-libraries)
|
1009
1107
|
- [Glimmer Process](#glimmer-process)
|
1010
1108
|
- [Help](#help)
|
1011
1109
|
- [Issues](#issues)
|
@@ -1025,7 +1123,7 @@ Learn more about the differences between various [Glimmer](https://github.com/An
|
|
1025
1123
|
|
1026
1124
|
## Setup
|
1027
1125
|
|
1028
|
-
(NOTE: Keep in mind this is
|
1126
|
+
(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)
|
1029
1127
|
|
1030
1128
|
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.
|
1031
1129
|
|
@@ -1048,7 +1146,7 @@ rails new glimmer_app_server
|
|
1048
1146
|
Add the following to `Gemfile`:
|
1049
1147
|
|
1050
1148
|
```
|
1051
|
-
gem 'glimmer-dsl-web', '~> 0.0
|
1149
|
+
gem 'glimmer-dsl-web', '~> 0.1.0'
|
1052
1150
|
```
|
1053
1151
|
|
1054
1152
|
Run:
|
@@ -1151,7 +1249,7 @@ Document.ready? do
|
|
1151
1249
|
label(class: 'greeting') {
|
1152
1250
|
'Hello, World!'
|
1153
1251
|
}
|
1154
|
-
}
|
1252
|
+
}
|
1155
1253
|
end
|
1156
1254
|
```
|
1157
1255
|
|
@@ -1202,7 +1300,7 @@ Document.ready? do
|
|
1202
1300
|
label(class: 'greeting') {
|
1203
1301
|
'Hello, World!'
|
1204
1302
|
}
|
1205
|
-
}
|
1303
|
+
}
|
1206
1304
|
end
|
1207
1305
|
```
|
1208
1306
|
|
@@ -1264,7 +1362,7 @@ Disable the `webpacker` gem line in `Gemfile`:
|
|
1264
1362
|
Add the following to `Gemfile`:
|
1265
1363
|
|
1266
1364
|
```ruby
|
1267
|
-
gem 'glimmer-dsl-web', '~> 0.0
|
1365
|
+
gem 'glimmer-dsl-web', '~> 0.1.0'
|
1268
1366
|
```
|
1269
1367
|
|
1270
1368
|
Run:
|
@@ -1365,7 +1463,7 @@ Document.ready? do
|
|
1365
1463
|
label(class: 'greeting') {
|
1366
1464
|
'Hello, World!'
|
1367
1465
|
}
|
1368
|
-
}
|
1466
|
+
}
|
1369
1467
|
end
|
1370
1468
|
```
|
1371
1469
|
|
@@ -1520,7 +1618,7 @@ include Glimmer
|
|
1520
1618
|
Document.ready? do
|
1521
1619
|
div {
|
1522
1620
|
'Hello, World!'
|
1523
|
-
}
|
1621
|
+
}
|
1524
1622
|
end
|
1525
1623
|
```
|
1526
1624
|
|
@@ -1542,7 +1640,7 @@ require 'glimmer-dsl-web'
|
|
1542
1640
|
include Glimmer
|
1543
1641
|
|
1544
1642
|
Document.ready? do
|
1545
|
-
div('Hello, World!')
|
1643
|
+
div('Hello, World!')
|
1546
1644
|
end
|
1547
1645
|
```
|
1548
1646
|
|
@@ -1574,7 +1672,7 @@ Document.ready? do
|
|
1574
1672
|
$$.alert('Hello, Button!')
|
1575
1673
|
end
|
1576
1674
|
}
|
1577
|
-
}
|
1675
|
+
}
|
1578
1676
|
end
|
1579
1677
|
```
|
1580
1678
|
|
@@ -1675,7 +1773,7 @@ Document.ready? do
|
|
1675
1773
|
}
|
1676
1774
|
CSS
|
1677
1775
|
}
|
1678
|
-
}
|
1776
|
+
}
|
1679
1777
|
end
|
1680
1778
|
```
|
1681
1779
|
|
@@ -1770,7 +1868,11 @@ class HelloObserver
|
|
1770
1868
|
end
|
1771
1869
|
|
1772
1870
|
after_render do
|
1773
|
-
|
1871
|
+
@number_input.value = @number_holder.number
|
1872
|
+
@range_input.value = @number_holder.number
|
1873
|
+
# Observe Model attribute @number_holder.number for changes and update View
|
1874
|
+
# Observer is automatically cleaned up if remove method is called on rendered HelloObserver
|
1875
|
+
# or its top-level element
|
1774
1876
|
observe(@number_holder, :number) do
|
1775
1877
|
number_string = @number_holder.number.to_s
|
1776
1878
|
@number_input.value = number_string unless @number_input.value == number_string
|
@@ -1785,7 +1887,7 @@ class HelloObserver
|
|
1785
1887
|
markup {
|
1786
1888
|
div {
|
1787
1889
|
div {
|
1788
|
-
@number_input = input(type: 'number',
|
1890
|
+
@number_input = input(type: 'number', min: 0, max: 100) {
|
1789
1891
|
# oninput listener updates Model attribute @number_holder.number
|
1790
1892
|
oninput do
|
1791
1893
|
@number_holder.number = @number_input.value.to_i
|
@@ -1799,7 +1901,7 @@ class HelloObserver
|
|
1799
1901
|
}
|
1800
1902
|
}
|
1801
1903
|
div {
|
1802
|
-
@range_input = input(type: 'range',
|
1904
|
+
@range_input = input(type: 'range', min: 0, max: 100) {
|
1803
1905
|
# oninput listener updates Model attribute @number_holder.number
|
1804
1906
|
oninput do
|
1805
1907
|
@number_holder.number = @range_input.value.to_i
|
@@ -1990,7 +2092,7 @@ Document.ready? do
|
|
1990
2092
|
computed_by: @address.members + ['state_code'],
|
1991
2093
|
]
|
1992
2094
|
}
|
1993
|
-
}
|
2095
|
+
}
|
1994
2096
|
end
|
1995
2097
|
```
|
1996
2098
|
|
@@ -2125,7 +2227,7 @@ Document.ready? do
|
|
2125
2227
|
end
|
2126
2228
|
end
|
2127
2229
|
}
|
2128
|
-
}
|
2230
|
+
}
|
2129
2231
|
end
|
2130
2232
|
```
|
2131
2233
|
|
@@ -2559,6 +2661,98 @@ Screenshot:
|
|
2559
2661
|
|
2560
2662
|
![Hello, glimmer_component Rails Helper!](/images/glimmer-dsl-web-samples-hello-hello-component.png)
|
2561
2663
|
|
2664
|
+
#### Hello, Paragraph!
|
2665
|
+
|
2666
|
+
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>`
|
2667
|
+
|
2668
|
+
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.
|
2669
|
+
|
2670
|
+
This enables writing code like:
|
2671
|
+
|
2672
|
+
`p {"#{strong('Yesterday, ')}Robert suggested adding a new #{em('feature')} to our software product.#{br}}`
|
2673
|
+
|
2674
|
+
That is close to how it is written in HTML, albeit briefer in Ruby:
|
2675
|
+
|
2676
|
+
`<p><strong>Yesterday, </strong>Robert suggested adding a new <em>feature</em> to our software product.<br></p>`
|
2677
|
+
|
2678
|
+
Formatting elements just like regular elements can accept text content as their first argument or as their block return value. So, the code above could equally be written as follows:
|
2679
|
+
|
2680
|
+
`p {"#{strong{'Yesterday, '}}Robert suggested adding a new #{em{'feature'}} to our software product.#{br}}`
|
2681
|
+
|
2682
|
+
This enables seggregating formatting element attributes if desired, as in this example:
|
2683
|
+
|
2684
|
+
`p {"#{strong(class: 'very-string'){'Yesterday, '}}Robert suggested adding a new #{em(class: 'very-emphasized'){'feature'}} to our software product.#{br}}`
|
2685
|
+
|
2686
|
+
Another way of writing the same code is to pass the text content as the first argument, before attributes:
|
2687
|
+
|
2688
|
+
|
2689
|
+
`p {"#{strong('Yesterday, ', class: 'very-string')}Robert suggested adding a new #{em('feature', class: 'very-emphasized')} to our software product.#{br}}`
|
2690
|
+
|
2691
|
+
One last bit of info to keep in mind is that `<span>` generally generates a normal element, except when used inside a `<p>`'s content block, in which case it is assumed to be used for formatting, so
|
2692
|
+
it returns a `String` to enable code like this:
|
2693
|
+
|
2694
|
+
`p {"#{span('Yesterday, ', style: 'text-decoration: underline;')}Robert suggested adding a new #{em('feature', class: 'very-emphasized')} to our software product.#{br}}`
|
2695
|
+
|
2696
|
+
In any case, below is a full example leveraging the Glimmer GUI DSL alternative approach when utilizing formatting elements underneath a paragraph.
|
2697
|
+
|
2698
|
+
Glimmer GUI code:
|
2699
|
+
|
2700
|
+
```ruby
|
2701
|
+
require 'glimmer-dsl-web'
|
2702
|
+
|
2703
|
+
class HelloParagraph
|
2704
|
+
include Glimmer::Web::Component
|
2705
|
+
|
2706
|
+
markup {
|
2707
|
+
div {
|
2708
|
+
h1(class: 'title') {
|
2709
|
+
'Flying Cars Become 100% Safe with AI Powered Balance!'
|
2710
|
+
}
|
2711
|
+
|
2712
|
+
p(class: 'intro') {"
|
2713
|
+
In the early 2030's, #{em('flying cars')} became affordable after their prices dropped
|
2714
|
+
below #{small(del('$100,000'))}#{ins('$80,000')} as a result of the innovations of #{strong('Travel-X')}. Still, that did not
|
2715
|
+
make #{em('flying cars')} any popular due to the extreme difficulty in piloting such flying vehicles for the average
|
2716
|
+
person, making it very tough to pass the tests for getting a piloting license given the learning curve.
|
2717
|
+
"}
|
2718
|
+
|
2719
|
+
p {"
|
2720
|
+
That said, #{b('Travel-X')} has recently come up with a new feature for their flagship #{i('flying car')},
|
2721
|
+
the Ptero#{sub(1)}#{sup('TM')}, which relies on AI#{sub(2)} to automatically balance the flying cars in mid-air,
|
2722
|
+
thus significantly facilitating their piloting by the average consumer.
|
2723
|
+
"}
|
2724
|
+
|
2725
|
+
p(class: 'conclusion') {"
|
2726
|
+
That Ptero#{sup('TM')} will be so stable and well balanced while flying that the consumer will be able to drive
|
2727
|
+
as if it is a plain old car, with the only difference being vertical elevation, the control of which will be handled
|
2728
|
+
automatically by AI. The Ptero#{sup('TM')} will debut for #{span(style: 'text-decoration: underline dashed;'){'$79,000'}}.
|
2729
|
+
"}
|
2730
|
+
|
2731
|
+
h2(class: 'legend-title') {
|
2732
|
+
mark('Legend:')
|
2733
|
+
}
|
2734
|
+
|
2735
|
+
p(class: 'legend') {"
|
2736
|
+
#{strong("1- Ptero:")} Pterosaur is flying dinosaur species#{br}
|
2737
|
+
#{strong("2- AI:")} Artificial Intelligence#{br}
|
2738
|
+
"}
|
2739
|
+
|
2740
|
+
}
|
2741
|
+
}
|
2742
|
+
end
|
2743
|
+
|
2744
|
+
Document.ready? do
|
2745
|
+
HelloParagraph.render
|
2746
|
+
end
|
2747
|
+
```
|
2748
|
+
|
2749
|
+
Screenshot:
|
2750
|
+
|
2751
|
+
--
|
2752
|
+
|
2753
|
+
![Hello, Paragraph!](/images/glimmer-dsl-web-samples-hello-hello-paragraph.png)
|
2754
|
+
|
2755
|
+
--
|
2562
2756
|
|
2563
2757
|
#### Hello, Input (Date/Time)!
|
2564
2758
|
|
@@ -2659,7 +2853,7 @@ Document.ready? do
|
|
2659
2853
|
CSS
|
2660
2854
|
}
|
2661
2855
|
}
|
2662
|
-
}
|
2856
|
+
}
|
2663
2857
|
end
|
2664
2858
|
```
|
2665
2859
|
|
@@ -2744,7 +2938,18 @@ Screenshot:
|
|
2744
2938
|
|
2745
2939
|
![Button Counter](/images/glimmer-dsl-web-samples-regular-button-counter.gif)
|
2746
2940
|
|
2747
|
-
##
|
2941
|
+
## Design Principles
|
2942
|
+
|
2943
|
+
- The Ruby Way (including TIMTOWTDI: There Is More Than One Way To Do It)
|
2944
|
+
- The Rails Way Convention over Configuration via smart defaults and automation of low-level details
|
2945
|
+
- Requiring the least amount of syntax possible to build highly interactive web pages
|
2946
|
+
- Declarative syntax that visually maps to the DOM (Document Object Model) hierarchy
|
2947
|
+
- Ability to mix declarative and imperative code conveniently in one language
|
2948
|
+
- Computers serve Software Engineers (not Software Engineers serve Computers)
|
2949
|
+
- Think only about real world concepts directly relevant to web page interaction
|
2950
|
+
- Modular Software Design (e.g. support for Components)
|
2951
|
+
|
2952
|
+
## Supporting Libraries
|
2748
2953
|
|
2749
2954
|
Here is a list of notable 3rd party gems used by Glimmer DSL for Web:
|
2750
2955
|
- [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML & HTML in pure Ruby.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/glimmer-dsl-web.gemspec
CHANGED
@@ -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.0
|
5
|
+
# stub: glimmer-dsl-web 0.1.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "glimmer-dsl-web".freeze
|
9
|
-
s.version = "0.0
|
9
|
+
s.version = "0.1.0".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-
|
15
|
-
s.description = "Glimmer DSL for Web (Ruby in the Browser Web GUI Frontend Library)
|
14
|
+
s.date = "2024-01-08"
|
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
|
16
16
|
s.email = "andy.am@gmail.com".freeze
|
17
17
|
s.extra_rdoc_files = [
|
18
18
|
"CHANGELOG.md",
|
@@ -38,6 +38,7 @@ Gem::Specification.new do |s|
|
|
38
38
|
"lib/glimmer-dsl-web/samples/hello/hello_glimmer_component_helper/address_form.rb",
|
39
39
|
"lib/glimmer-dsl-web/samples/hello/hello_input_date_time.rb",
|
40
40
|
"lib/glimmer-dsl-web/samples/hello/hello_observer.rb",
|
41
|
+
"lib/glimmer-dsl-web/samples/hello/hello_paragraph.rb",
|
41
42
|
"lib/glimmer-dsl-web/samples/hello/hello_world.rb",
|
42
43
|
"lib/glimmer-dsl-web/samples/regular/button_counter.rb",
|
43
44
|
"lib/glimmer-dsl-web/vendor/jquery.js",
|
@@ -49,6 +50,7 @@ Gem::Specification.new do |s|
|
|
49
50
|
"lib/glimmer/dsl/web/data_binding_expression.rb",
|
50
51
|
"lib/glimmer/dsl/web/dsl.rb",
|
51
52
|
"lib/glimmer/dsl/web/element_expression.rb",
|
53
|
+
"lib/glimmer/dsl/web/formatting_element_expression.rb",
|
52
54
|
"lib/glimmer/dsl/web/general_element_expression.rb",
|
53
55
|
"lib/glimmer/dsl/web/listener_expression.rb",
|
54
56
|
"lib/glimmer/dsl/web/observe_expression.rb",
|
@@ -62,6 +64,7 @@ Gem::Specification.new do |s|
|
|
62
64
|
"lib/glimmer/web/component.rb",
|
63
65
|
"lib/glimmer/web/element_proxy.rb",
|
64
66
|
"lib/glimmer/web/event_proxy.rb",
|
67
|
+
"lib/glimmer/web/formatting_element_proxy.rb",
|
65
68
|
"lib/glimmer/web/listener_proxy.rb"
|
66
69
|
]
|
67
70
|
s.homepage = "http://github.com/AndyObtiva/glimmer-dsl-web".freeze
|
data/lib/glimmer/dsl/web/dsl.rb
CHANGED
@@ -21,6 +21,7 @@
|
|
21
21
|
|
22
22
|
require 'glimmer/dsl/engine'
|
23
23
|
require 'glimmer/dsl/web/element_expression'
|
24
|
+
require 'glimmer/dsl/web/formatting_element_expression'
|
24
25
|
require 'glimmer/dsl/web/listener_expression'
|
25
26
|
require 'glimmer/dsl/web/property_expression'
|
26
27
|
require 'glimmer/dsl/web/p_expression'
|
@@ -44,6 +45,7 @@ module Glimmer
|
|
44
45
|
property
|
45
46
|
content_data_binding
|
46
47
|
shine_data_binding
|
48
|
+
formatting_element
|
47
49
|
element
|
48
50
|
]
|
49
51
|
)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'glimmer/dsl/expression'
|
2
|
+
|
3
|
+
require 'glimmer/web/formatting_element_proxy'
|
4
|
+
|
5
|
+
module Glimmer
|
6
|
+
module DSL
|
7
|
+
module Web
|
8
|
+
class FormattingElementExpression < Expression
|
9
|
+
def can_interpret?(parent, keyword, *args, &block)
|
10
|
+
Glimmer::Web::FormattingElementProxy.keyword_supported?(keyword, parent: parent)
|
11
|
+
end
|
12
|
+
|
13
|
+
def interpret(parent, keyword, *args, &block)
|
14
|
+
Glimmer::Web::FormattingElementProxy.format(keyword, *args, &block)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -93,10 +93,17 @@ module Glimmer
|
|
93
93
|
self.name.underscore.gsub('::', '__').split('__').last
|
94
94
|
end
|
95
95
|
|
96
|
+
# Creates component without rendering
|
97
|
+
def create(*args)
|
98
|
+
args << {} unless args.last.is_a?(Hash)
|
99
|
+
args.last[:render] = false
|
100
|
+
rendered_component = send(keyword, *args)
|
101
|
+
rendered_component
|
102
|
+
end
|
103
|
+
|
104
|
+
# Creates and renders component
|
96
105
|
def render(*args)
|
97
106
|
rendered_component = send(keyword, *args)
|
98
|
-
options = args.last.is_a?(Hash) ? args.last.slice(:parent, :custom_parent_dom_element, :brand_new) : {}
|
99
|
-
rendered_component.render(**options)
|
100
107
|
rendered_component
|
101
108
|
end
|
102
109
|
end
|
@@ -204,10 +211,15 @@ module Glimmer
|
|
204
211
|
markup_block = self.class.instance_variable_get("@markup_block")
|
205
212
|
raise Glimmer::Error, 'Invalid Glimmer web component for having no markup! Please define markup block!' if markup_block.nil?
|
206
213
|
@markup_root = instance_exec(&markup_block)
|
207
|
-
@markup_root.options[:parent] = options[:parent] if options[:parent]
|
214
|
+
@markup_root.options[:parent] = options[:parent] if !options[:parent].nil?
|
208
215
|
@parent ||= @markup_root.parent
|
209
216
|
raise Glimmer::Error, 'Invalid Glimmer web component for having an empty markup! Please fill markup block!' if @markup_root.nil?
|
210
|
-
|
217
|
+
if options[:render] != false
|
218
|
+
execute_hooks('after_render')
|
219
|
+
else
|
220
|
+
on_render_listener = proc { execute_hooks('after_render') }
|
221
|
+
@markup_root.handle_observation_request('on_render', on_render_listener)
|
222
|
+
end
|
211
223
|
|
212
224
|
# TODO adapt for web
|
213
225
|
observer_registration_cleanup_listener = proc do
|
@@ -109,16 +109,25 @@ module Glimmer
|
|
109
109
|
@keyword = keyword
|
110
110
|
@parent = parent
|
111
111
|
@options = args.last.is_a?(Hash) ? args.last.symbolize_keys : {}
|
112
|
+
if parent.nil?
|
113
|
+
options[:parent] ||= Component.interpretation_stack.last&.options&.[](:parent)
|
114
|
+
options[:render] ||= Component.interpretation_stack.last&.options&.[](:render)
|
115
|
+
end
|
112
116
|
@args = args
|
113
117
|
@block = block
|
114
118
|
@children = []
|
115
119
|
@parent&.post_initialize_child(self)
|
120
|
+
render if !@rendered && render_after_create?
|
121
|
+
end
|
122
|
+
|
123
|
+
def render_after_create?
|
124
|
+
options[:render] != false && (@parent.nil? || @parent.render_after_create?)
|
116
125
|
end
|
117
126
|
|
118
127
|
# Executes for the parent of a child that just got added
|
119
128
|
def post_initialize_child(child)
|
120
129
|
@children << child
|
121
|
-
child.render
|
130
|
+
child.render if !render_after_create?
|
122
131
|
end
|
123
132
|
|
124
133
|
# Executes for the parent of a child that just got removed
|
@@ -128,6 +137,7 @@ module Glimmer
|
|
128
137
|
|
129
138
|
# Executes at the closing of a parent widget curly braces after all children/properties have been added/set
|
130
139
|
def post_add_content
|
140
|
+
# TODO double check every place we should call this method
|
131
141
|
# No Op
|
132
142
|
end
|
133
143
|
|
@@ -215,7 +225,7 @@ module Glimmer
|
|
215
225
|
def parent_selector
|
216
226
|
@parent&.selector
|
217
227
|
end
|
218
|
-
|
228
|
+
|
219
229
|
def parent_dom_element
|
220
230
|
if parent_selector
|
221
231
|
Document.find(parent_selector)
|
@@ -253,8 +263,10 @@ module Glimmer
|
|
253
263
|
handle_observation_request(keyword, event_listener)
|
254
264
|
end
|
255
265
|
end
|
256
|
-
|
257
|
-
child
|
266
|
+
unless render_after_create?
|
267
|
+
children.each do |child|
|
268
|
+
child.render
|
269
|
+
end
|
258
270
|
end
|
259
271
|
@rendered = true
|
260
272
|
unless skip_content_on_render_blocks?
|
@@ -262,6 +274,10 @@ module Glimmer
|
|
262
274
|
content(&content_block)
|
263
275
|
end
|
264
276
|
end
|
277
|
+
# TODO replace following line with a method call like (`notify_listeners('on_render')`)
|
278
|
+
listeners_for('on_render').each do |listener|
|
279
|
+
listener.original_event_listener.call(EventProxy.new(listener: listener))
|
280
|
+
end
|
265
281
|
end
|
266
282
|
alias rerender render
|
267
283
|
|
@@ -302,6 +318,7 @@ module Glimmer
|
|
302
318
|
|
303
319
|
def dom
|
304
320
|
# TODO auto-convert known glimmer attributes like parent to data attributes like data-parent
|
321
|
+
# TODO check if we need to avoid rendering content block if no content is available
|
305
322
|
@dom ||= html {
|
306
323
|
send(keyword, html_options) {
|
307
324
|
args.first if args.first.is_a?(String)
|
@@ -0,0 +1,56 @@
|
|
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 Glimmer
|
25
|
+
module Web
|
26
|
+
class FormattingElementProxy
|
27
|
+
class << self
|
28
|
+
include Glimmer
|
29
|
+
|
30
|
+
def keyword_supported?(keyword, parent: nil)
|
31
|
+
keyword = keyword.to_s
|
32
|
+
(
|
33
|
+
FORMATTING_ELEMENT_KEYWORDS.include?(keyword) ||
|
34
|
+
(parent&.keyword == 'p' && keyword == 'span')
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
def format(keyword, *args, &block)
|
39
|
+
content = nil
|
40
|
+
if block_given?
|
41
|
+
content = block.call.to_s
|
42
|
+
elsif args.any? && !args.first.is_a?(Hash)
|
43
|
+
content = args.first.to_s
|
44
|
+
end
|
45
|
+
attribute_hash = args.last.is_a?(Hash) ? args.last : {}
|
46
|
+
content_block = proc { content } unless content.nil?
|
47
|
+
html {
|
48
|
+
send(keyword, attribute_hash, &content_block)
|
49
|
+
}.to_s
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
FORMATTING_ELEMENT_KEYWORDS = %w[b i strong em sub sup del ins small mark br]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -37,7 +37,11 @@ class HelloObserver
|
|
37
37
|
end
|
38
38
|
|
39
39
|
after_render do
|
40
|
-
|
40
|
+
@number_input.value = @number_holder.number
|
41
|
+
@range_input.value = @number_holder.number
|
42
|
+
# Observe Model attribute @number_holder.number for changes and update View
|
43
|
+
# Observer is automatically cleaned up if remove method is called on rendered HelloObserver
|
44
|
+
# or its top-level element
|
41
45
|
observe(@number_holder, :number) do
|
42
46
|
number_string = @number_holder.number.to_s
|
43
47
|
@number_input.value = number_string unless @number_input.value == number_string
|
@@ -52,7 +56,7 @@ class HelloObserver
|
|
52
56
|
markup {
|
53
57
|
div {
|
54
58
|
div {
|
55
|
-
@number_input = input(type: 'number',
|
59
|
+
@number_input = input(type: 'number', min: 0, max: 100) {
|
56
60
|
# oninput listener updates Model attribute @number_holder.number
|
57
61
|
oninput do
|
58
62
|
@number_holder.number = @number_input.value.to_i
|
@@ -66,7 +70,7 @@ class HelloObserver
|
|
66
70
|
}
|
67
71
|
}
|
68
72
|
div {
|
69
|
-
@range_input = input(type: 'range',
|
73
|
+
@range_input = input(type: 'range', min: 0, max: 100) {
|
70
74
|
# oninput listener updates Model attribute @number_holder.number
|
71
75
|
oninput do
|
72
76
|
@number_holder.number = @range_input.value.to_i
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# Copyright (c) 2023-2024 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
|
+
class HelloParagraph
|
25
|
+
include Glimmer::Web::Component
|
26
|
+
|
27
|
+
markup {
|
28
|
+
div {
|
29
|
+
h1(class: 'title') {
|
30
|
+
'Flying Cars Become 100% Safe with AI Powered Balance!'
|
31
|
+
}
|
32
|
+
|
33
|
+
p(class: 'intro') {"
|
34
|
+
In the early 2030's, #{em('flying cars')} became affordable after their prices dropped
|
35
|
+
below #{small(del('$100,000'))}#{ins('$80,000')} as a result of the innovations of #{strong('Travel-X')}. Still, that did not
|
36
|
+
make #{em('flying cars')} any popular due to the extreme difficulty in piloting such flying vehicles for the average
|
37
|
+
person, making it very tough to pass the tests for getting a piloting license given the learning curve.
|
38
|
+
"}
|
39
|
+
|
40
|
+
p {"
|
41
|
+
That said, #{b('Travel-X')} has recently come up with a new feature for their flagship #{i('flying car')},
|
42
|
+
the Ptero#{sub(1)}#{sup('TM')}, which relies on AI#{sub(2)} to automatically balance the flying cars in mid-air,
|
43
|
+
thus significantly facilitating their piloting by the average consumer.
|
44
|
+
"}
|
45
|
+
|
46
|
+
p(class: 'conclusion') {"
|
47
|
+
That Ptero#{sup('TM')} will be so stable and well balanced while flying that the consumer will be able to drive
|
48
|
+
as if it is a plain old car, with the only difference being vertical elevation, the control of which will be handled
|
49
|
+
automatically by AI. The Ptero#{sup('TM')} will debut for #{span(style: 'text-decoration: underline dashed;'){'$79,000'}}.
|
50
|
+
"}
|
51
|
+
|
52
|
+
h2(class: 'legend-title') {
|
53
|
+
mark('Legend:')
|
54
|
+
}
|
55
|
+
|
56
|
+
p(class: 'legend') {"
|
57
|
+
#{strong("1- Ptero:")} Pterosaur is flying dinosaur species#{br}
|
58
|
+
#{strong("2- AI:")} Artificial Intelligence#{br}
|
59
|
+
"}
|
60
|
+
|
61
|
+
}
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
Document.ready? do
|
66
|
+
HelloParagraph.render
|
67
|
+
end
|
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.0
|
4
|
+
version: 0.1.0
|
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-
|
11
|
+
date: 2024-01-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glimmer
|
@@ -230,10 +230,17 @@ 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)
|
234
|
-
|
235
|
-
|
236
|
-
|
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
|
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.
|
237
244
|
email: andy.am@gmail.com
|
238
245
|
executables: []
|
239
246
|
extensions: []
|
@@ -260,6 +267,7 @@ files:
|
|
260
267
|
- lib/glimmer-dsl-web/samples/hello/hello_glimmer_component_helper/address_form.rb
|
261
268
|
- lib/glimmer-dsl-web/samples/hello/hello_input_date_time.rb
|
262
269
|
- lib/glimmer-dsl-web/samples/hello/hello_observer.rb
|
270
|
+
- lib/glimmer-dsl-web/samples/hello/hello_paragraph.rb
|
263
271
|
- lib/glimmer-dsl-web/samples/hello/hello_world.rb
|
264
272
|
- lib/glimmer-dsl-web/samples/regular/button_counter.rb
|
265
273
|
- lib/glimmer-dsl-web/vendor/jquery.js
|
@@ -271,6 +279,7 @@ files:
|
|
271
279
|
- lib/glimmer/dsl/web/data_binding_expression.rb
|
272
280
|
- lib/glimmer/dsl/web/dsl.rb
|
273
281
|
- lib/glimmer/dsl/web/element_expression.rb
|
282
|
+
- lib/glimmer/dsl/web/formatting_element_expression.rb
|
274
283
|
- lib/glimmer/dsl/web/general_element_expression.rb
|
275
284
|
- lib/glimmer/dsl/web/listener_expression.rb
|
276
285
|
- lib/glimmer/dsl/web/observe_expression.rb
|
@@ -284,6 +293,7 @@ files:
|
|
284
293
|
- lib/glimmer/web/component.rb
|
285
294
|
- lib/glimmer/web/element_proxy.rb
|
286
295
|
- lib/glimmer/web/event_proxy.rb
|
296
|
+
- lib/glimmer/web/formatting_element_proxy.rb
|
287
297
|
- lib/glimmer/web/listener_proxy.rb
|
288
298
|
homepage: http://github.com/AndyObtiva/glimmer-dsl-web
|
289
299
|
licenses:
|