glimmer-dsl-web 0.10.2 → 0.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -1
- data/README.md +1 -1
- data/VERSION +1 -1
- data/glimmer-dsl-web.gemspec +4 -2
- data/lib/glimmer/dsl/web/general_element_expression.rb +5 -0
- data/lib/glimmer/web/component.rb +12 -0
- data/lib/glimmer/web/element_proxy.rb +32 -5
- data/lib/glimmer-dsl-web/samples/hello/hello_component_slots.rb +109 -105
- data/lib/glimmer-dsl-web/samples/hello/hello_mutation.rb +51 -0
- data/lib/glimmer-dsl-web/samples/hello/hello_mutation_content_data_binding.rb +83 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9612f4c1844bb9ccf62e32d1682a71bb933268fc9e9a74837a89a558001b96b0
|
|
4
|
+
data.tar.gz: c6bffc8d775f74c96f13cad87702648f2da115fd7da7de998946a7dc33572410
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5747a2f6092a03c2c0ae35c666f615aca23eac99b6b98eed533bf2876e747ca97bb33bd6a2f89285f34dcd0520873c2538e85306149cfbe5184fb921e4128928
|
|
7
|
+
data.tar.gz: 381d39d680af48941b8282aa180e4f6cd6641f7c79e408739c4e2e4838507f7e084011408f59dc09c5183c39912ec8b1cf6abbdadcff0f0587ec6d9151104d82
|
data/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 0.10.3
|
|
4
|
+
|
|
5
|
+
- Support `parent.prepend {}` on `ElementProxy` and `Glimmer::Web::Component`, which is a method that prepends elements to the content of a parent element
|
|
6
|
+
- Support `element.focused` & `element.focused=` methods, including `focused` data-binding support. Note that setting `element.focused=` as `true` gives an element focus, but setting it to `false` does not change focus (you would have to set another element as focused to remove focus from a previous element).
|
|
7
|
+
- Hello, Mutation! sample: `require 'glimmer-dsl-web/samples/hello/hello_mutation.rb'`
|
|
8
|
+
- Hello, Mutation Content Data-Binding! sample: `require 'glimmer-dsl-web/samples/hello/hello_mutation_content_data_binding.rb'`
|
|
9
|
+
|
|
3
10
|
## 0.10.2
|
|
4
11
|
|
|
5
|
-
- Support `
|
|
12
|
+
- Support `parent.append {}` as an alias for `content {}` on `ElementProxy` and `Glimmer::Web::Component`, which is a method that appends elements to the content of a parent element
|
|
6
13
|
|
|
7
14
|
## 0.10.1
|
|
8
15
|
|
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.10.
|
|
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.10.3 (Beta)
|
|
2
2
|
## Ruby-in-the-Browser Web Frontend Framework
|
|
3
3
|
### The "Rails" of Frontend Frameworks!!! ([Fukuoka Award Winning](https://andymaleh.blogspot.com/2025/01/glimmer-dsl-for-web-wins-in-fukuoka.html))
|
|
4
4
|
#### Finally, Ruby Developer Productivity, Happiness, and Fun in the Frontend!!!
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.10.
|
|
1
|
+
0.10.3
|
data/glimmer-dsl-web.gemspec
CHANGED
|
@@ -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.10.
|
|
5
|
+
# stub: glimmer-dsl-web 0.10.3 ruby lib
|
|
6
6
|
|
|
7
7
|
Gem::Specification.new do |s|
|
|
8
8
|
s.name = "glimmer-dsl-web".freeze
|
|
9
|
-
s.version = "0.10.
|
|
9
|
+
s.version = "0.10.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]
|
|
@@ -50,6 +50,8 @@ Gem::Specification.new do |s|
|
|
|
50
50
|
"lib/glimmer-dsl-web/samples/hello/hello_input_date_time.rb",
|
|
51
51
|
"lib/glimmer-dsl-web/samples/hello/hello_input_date_time_data_binding.rb",
|
|
52
52
|
"lib/glimmer-dsl-web/samples/hello/hello_modal.rb",
|
|
53
|
+
"lib/glimmer-dsl-web/samples/hello/hello_mutation.rb",
|
|
54
|
+
"lib/glimmer-dsl-web/samples/hello/hello_mutation_content_data_binding.rb",
|
|
53
55
|
"lib/glimmer-dsl-web/samples/hello/hello_observer.rb",
|
|
54
56
|
"lib/glimmer-dsl-web/samples/hello/hello_observer_data_binding.rb",
|
|
55
57
|
"lib/glimmer-dsl-web/samples/hello/hello_page_component_link/conference_talk_page.rb",
|
|
@@ -12,6 +12,9 @@ module Glimmer
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def add_content(parent, keyword, *args, &block)
|
|
15
|
+
options = args.last.is_a?(Hash) ? args.last : {}
|
|
16
|
+
parent_original_add_child_mutation = parent&.add_child_mutation
|
|
17
|
+
parent&.add_child_mutation = options[:add_child_mutation] if options[:add_child_mutation]
|
|
15
18
|
if parent.bulk_render? || parent.rendered? || parent.skip_content_on_render_blocks?
|
|
16
19
|
return_value = super(parent, keyword, *args, &block)
|
|
17
20
|
parent.add_text_content(return_value, on_empty: true) if return_value.is_a?(String)
|
|
@@ -20,6 +23,8 @@ module Glimmer
|
|
|
20
23
|
else
|
|
21
24
|
parent.add_content_on_render(&block)
|
|
22
25
|
end
|
|
26
|
+
ensure
|
|
27
|
+
parent&.add_child_mutation = parent_original_add_child_mutation
|
|
23
28
|
end
|
|
24
29
|
end
|
|
25
30
|
end
|
|
@@ -512,11 +512,23 @@ module Glimmer
|
|
|
512
512
|
end
|
|
513
513
|
alias append content
|
|
514
514
|
|
|
515
|
+
def prepend(bulk_render: false, &block)
|
|
516
|
+
@markup_root.prepend(bulk_render:, &block)
|
|
517
|
+
end
|
|
518
|
+
|
|
515
519
|
def remove_all_listeners
|
|
516
520
|
data_bindings.each do |option_binding, model_binding|
|
|
517
521
|
option_binding.unregister_all_observables
|
|
518
522
|
end
|
|
519
523
|
end
|
|
524
|
+
|
|
525
|
+
def add_child_mutation
|
|
526
|
+
markup_root.add_child_mutation
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
def add_child_mutation=(value)
|
|
530
|
+
markup_root.add_child_mutation = value
|
|
531
|
+
end
|
|
520
532
|
|
|
521
533
|
def method_missing(method_name, *args, &block)
|
|
522
534
|
if can_handle_observation_request?(method_name)
|
|
@@ -445,7 +445,7 @@ module Glimmer
|
|
|
445
445
|
brand_new ||= @dom.nil? || !options[:parent].to_s.empty? || (old_element = dom_element).empty?
|
|
446
446
|
build_dom(layout: !custom_parent_dom_element) # TODO handle custom parent layout by passing parent instead of parent dom element
|
|
447
447
|
if brand_new
|
|
448
|
-
attach(the_parent_dom_element)
|
|
448
|
+
attach(the_parent_dom_element, add_child_mutation: self.parent&.add_child_mutation || :append)
|
|
449
449
|
else
|
|
450
450
|
reattach(old_element)
|
|
451
451
|
end
|
|
@@ -458,14 +458,29 @@ module Glimmer
|
|
|
458
458
|
end
|
|
459
459
|
alias rerender render
|
|
460
460
|
|
|
461
|
-
def attach(the_parent_dom_element)
|
|
462
|
-
|
|
461
|
+
def attach(the_parent_dom_element, add_child_mutation: :append)
|
|
462
|
+
if add_child_mutation == :prepend
|
|
463
|
+
the_parent_dom_element.prepend(@dom)
|
|
464
|
+
else
|
|
465
|
+
the_parent_dom_element.append(@dom)
|
|
466
|
+
end
|
|
463
467
|
end
|
|
464
468
|
|
|
465
469
|
def reattach(old_element)
|
|
466
470
|
old_element.replace_with(@dom)
|
|
467
471
|
end
|
|
468
472
|
|
|
473
|
+
def focused
|
|
474
|
+
@focused = `#{dom_element}[0] == document.activeElement`
|
|
475
|
+
@focused
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
def focused=(value)
|
|
479
|
+
@focused = value
|
|
480
|
+
focus if @focused
|
|
481
|
+
@focused
|
|
482
|
+
end
|
|
483
|
+
|
|
469
484
|
def mark_rendered
|
|
470
485
|
@rendered = true
|
|
471
486
|
children.each(&:mark_rendered) if bulk_render?
|
|
@@ -545,15 +560,27 @@ module Glimmer
|
|
|
545
560
|
html_options
|
|
546
561
|
end
|
|
547
562
|
|
|
548
|
-
def
|
|
563
|
+
def add_child_mutation
|
|
564
|
+
@add_child_mutation || :append
|
|
565
|
+
end
|
|
566
|
+
|
|
567
|
+
def add_child_mutation=(value)
|
|
568
|
+
@add_child_mutation = value
|
|
569
|
+
end
|
|
570
|
+
|
|
571
|
+
def content(bulk_render: false, add_child_mutation: :append, &block)
|
|
549
572
|
original_bulk_render = options[:bulk_render]
|
|
550
573
|
options[:bulk_render] = bulk_render if rendered?
|
|
551
|
-
return_value = Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Web::ElementExpression.new, keyword, &block)
|
|
574
|
+
return_value = Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Web::ElementExpression.new, keyword, add_child_mutation:, &block)
|
|
552
575
|
options[:bulk_render] = original_bulk_render if rendered?
|
|
553
576
|
return_value
|
|
554
577
|
end
|
|
555
578
|
alias append content
|
|
556
579
|
|
|
580
|
+
def prepend(bulk_render: false, &block)
|
|
581
|
+
content(bulk_render:, add_child_mutation: :prepend, &block)
|
|
582
|
+
end
|
|
583
|
+
|
|
557
584
|
# Subclasses must override with their own mappings
|
|
558
585
|
def observation_request_to_event_mapping
|
|
559
586
|
{}
|
|
@@ -38,131 +38,135 @@ end
|
|
|
38
38
|
# generates a new Glimmer HTML DSL keyword that matches the lowercase underscored version
|
|
39
39
|
# of the name of the class. AddressForm generates address_form_with_slots keyword, which can be used
|
|
40
40
|
# elsewhere in Glimmer HTML DSL code as done inside HelloComponentSlots below.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
div(class: 'address-field-container', style: {display: :grid, grid_auto_columns: '80px 260px'}) {
|
|
54
|
-
label('Full Name: ', for: 'full-name-field')
|
|
55
|
-
input(id: 'full-name-field') {
|
|
56
|
-
value <=> [address, :full_name]
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
@somelabel = label('Street: ', for: 'street-field')
|
|
60
|
-
input(id: 'street-field') {
|
|
61
|
-
value <=> [address, :street]
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
label('Street 2: ', for: 'street2-field')
|
|
65
|
-
textarea(id: 'street2-field') {
|
|
66
|
-
value <=> [address, :street2]
|
|
67
|
-
}
|
|
41
|
+
unless Object.const_defined?(:AddressFormWithSlots)
|
|
42
|
+
class AddressFormWithSlots
|
|
43
|
+
include Glimmer::Web::Component
|
|
44
|
+
|
|
45
|
+
option :address
|
|
46
|
+
|
|
47
|
+
# markup block provides the content of the
|
|
48
|
+
markup {
|
|
49
|
+
div {
|
|
50
|
+
# designate this div as a slot with the slot name :address_header to enable
|
|
51
|
+
# consumers to contribute elements to `address_header {...}` slot
|
|
52
|
+
div(slot: :address_header, class: 'address-form-header')
|
|
68
53
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
54
|
+
div(class: 'address-field-container', style: {display: :grid, grid_auto_columns: '80px 260px'}) {
|
|
55
|
+
label('Full Name: ', for: 'full-name-field')
|
|
56
|
+
input(id: 'full-name-field') {
|
|
57
|
+
value <=> [address, :full_name]
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@somelabel = label('Street: ', for: 'street-field')
|
|
61
|
+
input(id: 'street-field') {
|
|
62
|
+
value <=> [address, :street]
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
label('Street 2: ', for: 'street2-field')
|
|
66
|
+
textarea(id: 'street2-field') {
|
|
67
|
+
value <=> [address, :street2]
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
label('City: ', for: 'city-field')
|
|
71
|
+
input(id: 'city-field') {
|
|
72
|
+
value <=> [address, :city]
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
label('State: ', for: 'state-field')
|
|
76
|
+
select(id: 'state-field') {
|
|
77
|
+
Address::STATES.each do |state_code, state|
|
|
78
|
+
option(value: state_code) { state }
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
value <=> [address, :state_code]
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
label('Zip Code: ', for: 'zip-code-field')
|
|
85
|
+
input(id: 'zip-code-field', type: 'number', min: '0', max: '99999') {
|
|
86
|
+
value <=> [address, :zip_code,
|
|
87
|
+
on_write: :to_s,
|
|
88
|
+
]
|
|
89
|
+
}
|
|
72
90
|
}
|
|
73
91
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
value <=> [address, :state_code]
|
|
92
|
+
div(style: {margin: 5}) {
|
|
93
|
+
inner_text <= [address, :summary,
|
|
94
|
+
computed_by: address.members + ['state_code'],
|
|
95
|
+
]
|
|
81
96
|
}
|
|
82
97
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
on_write: :to_s,
|
|
87
|
-
]
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
div(style: {margin: 5}) {
|
|
92
|
-
inner_text <= [address, :summary,
|
|
93
|
-
computed_by: address.members + ['state_code'],
|
|
94
|
-
]
|
|
98
|
+
# designate this div as a slot with the slot name :address_footer to enable
|
|
99
|
+
# consumers to contribute elements to `address_footer {...}` slot
|
|
100
|
+
div(slot: :address_footer, class: 'address-form-footer')
|
|
95
101
|
}
|
|
96
|
-
|
|
97
|
-
# designate this div as a slot with the slot name :address_footer to enable
|
|
98
|
-
# consumers to contribute elements to `address_footer {...}` slot
|
|
99
|
-
div(slot: :address_footer, class: 'address-form-footer')
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
style {
|
|
104
|
-
r('.address-field-container *') {
|
|
105
|
-
margin 5
|
|
106
102
|
}
|
|
107
|
-
|
|
108
|
-
|
|
103
|
+
|
|
104
|
+
style {
|
|
105
|
+
r('.address-field-container *') {
|
|
106
|
+
margin 5
|
|
107
|
+
}
|
|
108
|
+
r('.address-field-container input, .address-field-container select') {
|
|
109
|
+
grid_column '2'
|
|
110
|
+
}
|
|
109
111
|
}
|
|
110
|
-
|
|
112
|
+
end
|
|
111
113
|
end
|
|
112
114
|
|
|
113
115
|
# HelloComponentSlots Glimmer Web Component (View component)
|
|
114
116
|
#
|
|
115
117
|
# This View component represents the main page being rendered,
|
|
116
118
|
# as done by its `render` class method below
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
119
|
+
unless Object.const_defined?(:HelloComponentSlots)
|
|
120
|
+
class HelloComponentSlots
|
|
121
|
+
include Glimmer::Web::Component
|
|
122
|
+
|
|
123
|
+
before_render do
|
|
124
|
+
@shipping_address = Address.new(
|
|
125
|
+
full_name: 'Johnny Doe',
|
|
126
|
+
street: '3922 Park Ave',
|
|
127
|
+
street2: 'PO BOX 8382',
|
|
128
|
+
city: 'San Diego',
|
|
129
|
+
state: 'California',
|
|
130
|
+
zip_code: '91913',
|
|
131
|
+
)
|
|
132
|
+
@billing_address = Address.new(
|
|
133
|
+
full_name: 'John C Doe',
|
|
134
|
+
street: '123 Main St',
|
|
135
|
+
street2: 'Apartment 3C',
|
|
136
|
+
city: 'San Diego',
|
|
137
|
+
state: 'California',
|
|
138
|
+
zip_code: '91911',
|
|
139
|
+
)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
markup {
|
|
143
|
+
div {
|
|
144
|
+
address_form_with_slots(address: @shipping_address) {
|
|
145
|
+
address_header { # contribute elements to the address_header component slot
|
|
146
|
+
h1('Shipping Address')
|
|
147
|
+
legend('This is the address that is used for shipping your purchase.', style: {margin_bottom: 10})
|
|
148
|
+
}
|
|
149
|
+
address_footer { # contribute elements to the address_footer component slot
|
|
150
|
+
p {
|
|
151
|
+
sub("#{strong('Note:')} #{em('Purchase will be returned if the Shipping Address does not accept it in one week.')}")
|
|
152
|
+
}
|
|
149
153
|
}
|
|
150
154
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
155
|
+
|
|
156
|
+
address_form_with_slots(address: @billing_address) {
|
|
157
|
+
address_header { # contribute elements to the address_header component slot
|
|
158
|
+
h1('Billing Address')
|
|
159
|
+
legend('This is the address that is used for your billing method (e.g. credit card).', style: {margin_bottom: 10})
|
|
160
|
+
}
|
|
161
|
+
address_footer { # contribute elements to the address_footer component slot
|
|
162
|
+
p {
|
|
163
|
+
sub("#{strong('Note:')} #{em('Payment will fail if payment method does not match the Billing Address.')}")
|
|
164
|
+
}
|
|
161
165
|
}
|
|
162
166
|
}
|
|
163
167
|
}
|
|
164
168
|
}
|
|
165
|
-
|
|
169
|
+
end
|
|
166
170
|
end
|
|
167
171
|
|
|
168
172
|
Document.ready? do
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'glimmer-dsl-web'
|
|
2
|
+
|
|
3
|
+
class HelloMutation
|
|
4
|
+
include Glimmer::Web::Component
|
|
5
|
+
|
|
6
|
+
markup {
|
|
7
|
+
div {
|
|
8
|
+
h1('Hello, Mutation!')
|
|
9
|
+
|
|
10
|
+
p {
|
|
11
|
+
'Add items to a list via element DOM mutations.'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
div(class: 'actions') {
|
|
15
|
+
@input = input(placeholder: 'Enter list item content')
|
|
16
|
+
|
|
17
|
+
button('Append list item') {
|
|
18
|
+
onclick do
|
|
19
|
+
@list.append {
|
|
20
|
+
li { @input.value }
|
|
21
|
+
}
|
|
22
|
+
@input.value = ''
|
|
23
|
+
@input.focus
|
|
24
|
+
end
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
button('Prepend list item') {
|
|
28
|
+
onclick do
|
|
29
|
+
@list.prepend {
|
|
30
|
+
li { @input.value }
|
|
31
|
+
}
|
|
32
|
+
@input.value = ''
|
|
33
|
+
@input.focus
|
|
34
|
+
end
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@list = ul
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
style {
|
|
43
|
+
r('.actions input, .actions button') {
|
|
44
|
+
margin '10px 10px 10px 0'
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
Document.ready? do
|
|
50
|
+
HelloMutation.render
|
|
51
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require 'glimmer-dsl-web'
|
|
2
|
+
|
|
3
|
+
class ListPresenter
|
|
4
|
+
attr_accessor :list, :new_list_item
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
@list = []
|
|
8
|
+
@new_list_item = ''
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def append_list_item
|
|
12
|
+
list.push(new_list_item)
|
|
13
|
+
clear_new_list_item
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def prepend_list_item
|
|
17
|
+
list.prepend(new_list_item)
|
|
18
|
+
clear_new_list_item
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def clear_new_list_item
|
|
22
|
+
self.new_list_item = ''
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def entering_new_list_item?
|
|
26
|
+
new_list_item.empty?
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class HelloMutationContentDataBinding
|
|
31
|
+
include Glimmer::Web::Component
|
|
32
|
+
|
|
33
|
+
before_render do
|
|
34
|
+
@list_presenter = ListPresenter.new
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
markup {
|
|
38
|
+
div {
|
|
39
|
+
h1('Hello, Mutation Content Data-Binding!')
|
|
40
|
+
|
|
41
|
+
p {
|
|
42
|
+
'Add items to a list via content data-binding (which performs implicit DOM mutations).'
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
div(class: 'actions') {
|
|
46
|
+
@input = input(placeholder: 'Enter list item content') {
|
|
47
|
+
value <=> [@list_presenter, :new_list_item]
|
|
48
|
+
focused <= [@list_presenter, :entering_new_list_item?, computed_by: :new_list_item]
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
button('Append list item') {
|
|
52
|
+
onclick do
|
|
53
|
+
@list_presenter.append_list_item
|
|
54
|
+
end
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
button('Prepend list item') {
|
|
58
|
+
onclick do
|
|
59
|
+
@list_presenter.prepend_list_item
|
|
60
|
+
end
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
ul {
|
|
65
|
+
content(@list_presenter, :list) {
|
|
66
|
+
@list_presenter.list.each do |list_item|
|
|
67
|
+
li { list_item }
|
|
68
|
+
end
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
style {
|
|
75
|
+
r('.actions input, .actions button') {
|
|
76
|
+
margin '10px 10px 10px 0'
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
Document.ready? do
|
|
82
|
+
HelloMutationContentDataBinding.render
|
|
83
|
+
end
|
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.10.
|
|
4
|
+
version: 0.10.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andy Maleh
|
|
@@ -323,6 +323,8 @@ files:
|
|
|
323
323
|
- lib/glimmer-dsl-web/samples/hello/hello_input_date_time.rb
|
|
324
324
|
- lib/glimmer-dsl-web/samples/hello/hello_input_date_time_data_binding.rb
|
|
325
325
|
- lib/glimmer-dsl-web/samples/hello/hello_modal.rb
|
|
326
|
+
- lib/glimmer-dsl-web/samples/hello/hello_mutation.rb
|
|
327
|
+
- lib/glimmer-dsl-web/samples/hello/hello_mutation_content_data_binding.rb
|
|
326
328
|
- lib/glimmer-dsl-web/samples/hello/hello_observer.rb
|
|
327
329
|
- lib/glimmer-dsl-web/samples/hello/hello_observer_data_binding.rb
|
|
328
330
|
- lib/glimmer-dsl-web/samples/hello/hello_page_component_link/conference_talk_page.rb
|