cable_ready 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +2 -2
- data/README.md +131 -31
- data/lib/cable_ready/broadcaster.rb +67 -15
- data/lib/cable_ready/version.rb +1 -1
- data/vendor/assets/javascripts/cable_ready.js +71 -29
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4af592b2c92fa517e06a99e0f7c352be90c65ca7
|
4
|
+
data.tar.gz: 6f471df22a630daed758c14b8a141dfc4584a3bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e33789c536e4d878808de59eac1db026224bb0c61eb948d3adc13ff93f0768ed3adc7f0dd971c51f13b82765c5e1bbb443e5f0b8c311b543d6f092b7109b814d
|
7
|
+
data.tar.gz: 005ce8accba916cf3e297d5262c4e51c1ddd1eba242a8e189c4548055c68492b977c4640046d8aaa66bef40522101a3af16496c006dffd8c85ab84eef4912aef
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,81 +1,181 @@
|
|
1
|
-
[![Lines of Code](http://img.shields.io/badge/lines_of_code-
|
1
|
+
[![Lines of Code](http://img.shields.io/badge/lines_of_code-98-brightgreen.svg?style=flat)](http://blog.codinghorror.com/the-best-code-is-no-code-at-all/)
|
2
2
|
[![Code Status](http://img.shields.io/codeclimate/github/hopsoft/cable_ready.svg?style=flat)](https://codeclimate.com/github/hopsoft/cable_ready)
|
3
3
|
[![Dependency Status](http://img.shields.io/gemnasium/hopsoft/cable_ready.svg?style=flat)](https://gemnasium.com/hopsoft/cable_ready)
|
4
4
|
|
5
5
|
# CableReady
|
6
6
|
|
7
7
|
CableReady provides a standard interface for invoking common client-side DOM operations
|
8
|
-
from the server via
|
8
|
+
from the server via [ActionCable](http://guides.rubyonrails.org/action_cable_overview.html).
|
9
9
|
|
10
|
-
|
10
|
+
Learn more about CableReady by reading through & running the [CableReady Test](https://github.com/hopsoft/cable_ready_test) project.
|
11
11
|
|
12
12
|
## Supported DOM Operations
|
13
13
|
|
14
|
-
|
14
|
+
> The `selector` options use [Document.querySelector()](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector) to find elements.
|
15
|
+
|
16
|
+
> It's possible to invoke multiple DOM operations with a single ActionCable broadcast.
|
17
|
+
|
18
|
+
### DOM Events
|
19
|
+
|
20
|
+
#### [dispatchEvent](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent)
|
15
21
|
|
16
22
|
Dispatches a DOM event in the browser.
|
17
23
|
|
18
24
|
```ruby
|
19
25
|
cable_ready_broadcast "MyChannel", dispatch_event: [{
|
20
|
-
|
21
|
-
|
22
|
-
|
26
|
+
name: "string", # required - the name of the DOM event to dispatch (can be custom)
|
27
|
+
detail: "object", # [null] - assigned to event.detail
|
28
|
+
selector: "string" # [window] - string containing one or more CSS selectors separated by commas
|
23
29
|
}]
|
24
30
|
```
|
25
31
|
|
26
|
-
###
|
32
|
+
### Element Mutations
|
33
|
+
|
34
|
+
#### [innerHTML](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML)
|
27
35
|
|
28
36
|
Sets the innerHTML of a DOM element.
|
29
37
|
|
30
38
|
```ruby
|
31
39
|
cable_ready_broadcast "MyChannel", inner_html: [{
|
32
|
-
|
33
|
-
|
40
|
+
selector: "string", # required - string containing one or more CSS selectors separated by commas
|
41
|
+
focusSelector: "string", # [null] - string containing one or more CSS selectors separated by commas
|
42
|
+
html: "string" # [null] - the HTML to assign
|
34
43
|
}]
|
35
44
|
```
|
36
45
|
|
37
|
-
|
46
|
+
#### [textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent)
|
47
|
+
|
48
|
+
Sets the text content of a DOM element.
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
cable_ready_broadcast "MyChannel", text_content: [{
|
52
|
+
selector: "string", # required - string containing one or more CSS selectors separated by commas
|
53
|
+
text: "string" # [null] - the text to assign
|
54
|
+
}]
|
55
|
+
```
|
56
|
+
|
57
|
+
#### [insertAdjacentHTML](https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML)
|
38
58
|
|
39
59
|
Inserts HTML into the DOM relative to an element.
|
40
60
|
Supports behavior akin to prepend & append.
|
41
61
|
|
42
62
|
```ruby
|
43
63
|
cable_ready_broadcast "MyChannel", insert_adjacent_html: [{
|
44
|
-
|
45
|
-
|
46
|
-
|
64
|
+
selector: "string", # required - string containing one or more CSS selectors separated by commas
|
65
|
+
focusSelector: "string", # [null] - string containing one or more CSS selectors separated by commas
|
66
|
+
position: "string", # [beforeend] - the relative position to the DOM element (beforebegin, afterbegin, beforeend, afterend)
|
67
|
+
html: "string" # [null] - the HTML to insert
|
47
68
|
}]
|
48
69
|
```
|
49
70
|
|
50
|
-
|
71
|
+
#### [insertAdjacentText](https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentText)
|
72
|
+
|
73
|
+
Inserts text into the DOM relative to an element.
|
74
|
+
Supports behavior akin to prepend & append.
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
cable_ready_broadcast "MyChannel", insert_adjacent_text: [{
|
78
|
+
selector: "string", # required - string containing one or more CSS selectors separated by commas
|
79
|
+
position: "string", # [beforeend] - the relative position to the DOM element (beforebegin, afterbegin, beforeend, afterend)
|
80
|
+
text: "string" # [null] - the text to insert
|
81
|
+
}]
|
82
|
+
```
|
83
|
+
|
84
|
+
#### [remove](https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove)
|
51
85
|
|
52
86
|
Removes an element from the DOM.
|
53
87
|
|
54
88
|
```ruby
|
55
89
|
cable_ready_broadcast "MyChannel", remove: [{
|
56
|
-
|
90
|
+
selector: "string", # required - string containing one or more CSS selectors separated by commas
|
91
|
+
focusSelector: "string" # [null] - string containing one or more CSS selectors separated by commas
|
57
92
|
}]
|
58
93
|
```
|
59
94
|
|
60
|
-
|
95
|
+
#### [replace](https://developer.mozilla.org/en-US/docs/Web/API/Node/replaceChild)
|
61
96
|
|
62
97
|
Replaces a DOM element with new HTML.
|
63
98
|
|
64
99
|
```ruby
|
65
100
|
cable_ready_broadcast "MyChannel", replace: [{
|
66
|
-
|
67
|
-
|
101
|
+
selector: "string", # required - string containing one or more CSS selectors separated by commas
|
102
|
+
focusSelector: "string", # [null] - string containing one or more CSS selectors separated by commas
|
103
|
+
html: "string" # [null] - the HTML to use as replacement
|
68
104
|
}]
|
69
105
|
```
|
70
106
|
|
71
|
-
|
107
|
+
#### [setValue](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement)
|
72
108
|
|
73
|
-
Sets the
|
109
|
+
Sets the value of an element.
|
74
110
|
|
75
111
|
```ruby
|
76
|
-
cable_ready_broadcast "MyChannel",
|
77
|
-
|
78
|
-
|
112
|
+
cable_ready_broadcast "MyChannel", set_value: [{
|
113
|
+
selector: "string", # required - string containing one or more CSS selectors separated by commas
|
114
|
+
value: "string" # [null] - the value to assign to the attribute
|
115
|
+
}]
|
116
|
+
```
|
117
|
+
|
118
|
+
### Attribute Mutations
|
119
|
+
|
120
|
+
#### [setAttribute](https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute)
|
121
|
+
|
122
|
+
Sets an attribute on an element.
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
cable_ready_broadcast "MyChannel", set_attribute: [{
|
126
|
+
selector: "string", # required - string containing one or more CSS selectors separated by commas
|
127
|
+
name: "string", # required - the attribute to set
|
128
|
+
value: "string" # [null] - the value to assign to the attribute
|
129
|
+
}]
|
130
|
+
```
|
131
|
+
|
132
|
+
#### [removeAttribute](https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute)
|
133
|
+
|
134
|
+
Removes an attribute from an element.
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
cable_ready_broadcast "MyChannel", remove_attribute: [{
|
138
|
+
selector: "string", # required - string containing one or more CSS selectors separated by commas
|
139
|
+
name: "string" # required - the attribute to remove
|
140
|
+
}]
|
141
|
+
```
|
142
|
+
|
143
|
+
### CSS Class Mutations
|
144
|
+
|
145
|
+
#### [addCssClass](https://developer.mozilla.org/en-US/docs/Web/API/Element/classList)
|
146
|
+
|
147
|
+
Adds a css class to an element.
|
148
|
+
This is a `noop` if the css class is already assigned.
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
cable_ready_broadcast "MyChannel", add_css_class: [{
|
152
|
+
selector: "string", # required - string containing one or more CSS selectors separated by commas
|
153
|
+
name: "string" # [null] - the CSS class to add
|
154
|
+
}]
|
155
|
+
|
156
|
+
```
|
157
|
+
#### [removeCssClass](https://developer.mozilla.org/en-US/docs/Web/API/Element/classList)
|
158
|
+
|
159
|
+
Removes a css class from an element.
|
160
|
+
|
161
|
+
```ruby
|
162
|
+
cable_ready_broadcast "MyChannel", add_css_class: [{
|
163
|
+
selector: "string", # required - string containing one or more CSS selectors separated by commas
|
164
|
+
name: "string" # [null] - the CSS class to remove
|
165
|
+
}]
|
166
|
+
```
|
167
|
+
|
168
|
+
### Dataset Mutations
|
169
|
+
|
170
|
+
#### [setDatasetProperty](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset)
|
171
|
+
|
172
|
+
Sets an dataset property (data-* attribute) on an element.
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
cable_ready_broadcast "MyChannel", set_dataset_property: [{
|
176
|
+
selector: "string", # required - string containing one or more CSS selectors separated by commas
|
177
|
+
name: "string", # required - the property to set
|
178
|
+
value: "string" # [null] - the value to assign to the dataset
|
79
179
|
}]
|
80
180
|
```
|
81
181
|
|
@@ -89,7 +189,7 @@ class User < ApplicationRecord
|
|
89
189
|
include CableReady::Broadcaster
|
90
190
|
|
91
191
|
def broadcast_name_change
|
92
|
-
cable_ready_broadcast "UserChannel", text_content: [{
|
192
|
+
cable_ready_broadcast "UserChannel", text_content: [{ selector: "#user-name", text: name }]
|
93
193
|
end
|
94
194
|
end
|
95
195
|
```
|
@@ -114,11 +214,11 @@ App.cable.subscriptions.create({ channel: "UserChannel" }, {
|
|
114
214
|
});
|
115
215
|
```
|
116
216
|
|
117
|
-
## Testing & Experimenting
|
118
|
-
|
119
|
-
Learn more about CableReady by running the [CableReady Test](https://github.com/hopsoft/cable_ready_test) project.
|
120
|
-
|
121
217
|
## Advanced Usage
|
122
218
|
|
123
|
-
|
124
|
-
[SelfRenderer](https://github.com/hopsoft/self_renderer)
|
219
|
+
Consider using CableReady in concert with a gem like
|
220
|
+
[SelfRenderer](https://github.com/hopsoft/self_renderer) to create a powerful SPA style user experience with the simplicity of server side rendering.
|
221
|
+
|
222
|
+
<a target='_blank' rel='nofollow' href='https://app.codesponsor.io/link/QMSjMHrtPhvfmCnk5Hbikhhr/hopsoft/cable_ready'>
|
223
|
+
<img alt='Sponsor' width='888' height='68' src='https://app.codesponsor.io/embed/QMSjMHrtPhvfmCnk5Hbikhhr/hopsoft/cable_ready.svg' />
|
224
|
+
</a>
|
@@ -5,36 +5,88 @@ module CableReady
|
|
5
5
|
# Example Payload:
|
6
6
|
#
|
7
7
|
# {
|
8
|
+
# # DOM Events ..................................................................................................
|
9
|
+
#
|
8
10
|
# dispatch_event: [{
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
11
|
+
# name: "string",
|
12
|
+
# detail: "object",
|
13
|
+
# selector: "string",
|
12
14
|
# }, ...],
|
13
15
|
#
|
16
|
+
# # Element Mutations ...........................................................................................
|
17
|
+
#
|
14
18
|
# inner_html: [{
|
15
|
-
#
|
16
|
-
#
|
19
|
+
# selector: "string",
|
20
|
+
# focusSelector: "string",
|
21
|
+
# html: "string"
|
17
22
|
# }, ...],
|
18
23
|
#
|
24
|
+
# text_content: [{
|
25
|
+
# selector: "string",
|
26
|
+
# text: "string"
|
27
|
+
# }, ...]
|
28
|
+
#
|
19
29
|
# insert_adjacent_html: [{
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
30
|
+
# selector: "string",
|
31
|
+
# focusSelector: "string",
|
32
|
+
# position: "string",
|
33
|
+
# html: "string"
|
34
|
+
# }, ...],
|
35
|
+
#
|
36
|
+
# insert_adjacent_text: [{
|
37
|
+
# selector: "string",
|
38
|
+
# position: "string",
|
39
|
+
# text: "string"
|
23
40
|
# }, ...],
|
24
41
|
#
|
25
42
|
# remove: [{
|
26
|
-
#
|
43
|
+
# selector: "string",
|
44
|
+
# focusSelector: "string,
|
27
45
|
# }, ...],
|
28
46
|
#
|
29
47
|
# replace: [{
|
30
|
-
#
|
31
|
-
#
|
48
|
+
# selector: "string",
|
49
|
+
# focusSelector: "string",
|
50
|
+
# html: "string"
|
32
51
|
# }, ...],
|
33
52
|
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
# }, ...]
|
53
|
+
# set_value: [{
|
54
|
+
# selector: "string",
|
55
|
+
# value: "string"
|
56
|
+
# }, ...],
|
57
|
+
#
|
58
|
+
# # Attribute Mutations .........................................................................................
|
59
|
+
#
|
60
|
+
# set_attribute: [{
|
61
|
+
# selector: "string",
|
62
|
+
# name: "string",
|
63
|
+
# value: "string"
|
64
|
+
# }, ...],
|
65
|
+
#
|
66
|
+
# remove_attribute: [{
|
67
|
+
# selector: "string",
|
68
|
+
# name: "string"
|
69
|
+
# }, ...],
|
70
|
+
#
|
71
|
+
# # CSS Class Mutations .........................................................................................
|
72
|
+
#
|
73
|
+
# add_css_class: [{
|
74
|
+
# selector: "string",
|
75
|
+
# name: "string"
|
76
|
+
# }, ...],
|
77
|
+
#
|
78
|
+
# remove_css_class: [{
|
79
|
+
# selector: "string",
|
80
|
+
# name: "string"
|
81
|
+
# }, ...],
|
82
|
+
#
|
83
|
+
# # Dataset Mutations ...........................................................................................
|
84
|
+
#
|
85
|
+
# set_dataset_property: [{
|
86
|
+
# selector: "string",
|
87
|
+
# name: "string",
|
88
|
+
# value: "string"
|
89
|
+
# }, ...],
|
38
90
|
# }
|
39
91
|
def cable_ready_broadcast(channel, operations={})
|
40
92
|
operations ||= {}
|
data/lib/cable_ready/version.rb
CHANGED
@@ -1,52 +1,90 @@
|
|
1
1
|
(function () {
|
2
2
|
"use strict";
|
3
3
|
|
4
|
-
function log (operation, config) {
|
5
|
-
if (window.CableReady.debug) {
|
6
|
-
console.log("CableReady", operation, config);
|
7
|
-
}
|
8
|
-
}
|
9
|
-
|
10
4
|
var CableReadyOperations = {
|
5
|
+
// DOM Events .....................................................................................................
|
6
|
+
|
11
7
|
dispatchEvent: function (config) {
|
12
|
-
log("dispatchEvent", config);
|
13
|
-
var
|
14
|
-
var
|
15
|
-
var event = new Event(config.eventName);
|
8
|
+
if (CableReady.debug) { console.log("CableReady.dispatchEvent", config); }
|
9
|
+
var target = document.querySelector(config.selector) || window;
|
10
|
+
var event = new Event(config.name);
|
16
11
|
event.detail = config.detail;
|
17
12
|
target.dispatchEvent(event);
|
18
13
|
},
|
19
14
|
|
15
|
+
// Element Mutations ..............................................................................................
|
16
|
+
|
20
17
|
innerHtml: function (config) {
|
21
|
-
log("innerHTML", config);
|
22
|
-
|
23
|
-
|
18
|
+
if (CableReady.debug) { console.log("CableReady.innerHTML", config); }
|
19
|
+
document.querySelector(config.selector).innerHTML = config.html;
|
20
|
+
if (config.focusSelector) { document.querySelector(config.focusSelector).focus(); }
|
21
|
+
},
|
22
|
+
|
23
|
+
textContent: function (config) {
|
24
|
+
if (CableReady.debug) { console.log("CableReady.textContent", config); }
|
25
|
+
document.querySelector(config.selector).textContent = config.text;
|
24
26
|
},
|
25
27
|
|
26
28
|
insertAdjacentHtml: function (config) {
|
27
|
-
log("insertAdjacentHTML", config);
|
28
|
-
|
29
|
-
|
29
|
+
if (CableReady.debug) { console.log("CableReady.insertAdjacentHTML", config); }
|
30
|
+
document.querySelector(config.selector).insertAdjacentHTML(config.position || "beforeend", config.html);
|
31
|
+
if (config.focusSelector) { document.querySelector(config.focusSelector).focus(); }
|
32
|
+
},
|
33
|
+
|
34
|
+
insertAdjacentText: function (config) {
|
35
|
+
if (CableReady.debug) { console.log("CableReady.insertAdjacentText", config); }
|
36
|
+
document.querySelector(config.querySelector).insertAdjacentText(config.position || "beforeend", config.text);
|
30
37
|
},
|
31
38
|
|
32
39
|
remove: function (config) {
|
33
|
-
log("remove", config);
|
34
|
-
|
35
|
-
|
40
|
+
if (CableReady.debug) { console.log("CableReady.remove", config); }
|
41
|
+
document.querySelector(config.selector).remove();
|
42
|
+
if (config.focusSelector) { document.querySelector(config.focusSelector).focus(); }
|
36
43
|
},
|
37
44
|
|
38
45
|
replace: function (config) {
|
39
|
-
log("replace", config);
|
40
|
-
var element
|
41
|
-
var
|
42
|
-
|
43
|
-
element.parentNode.replaceChild(
|
46
|
+
if (CableReady.debug) { console.log("CableReady.replace", config); }
|
47
|
+
var element = document.querySelector(config.selector);
|
48
|
+
var div = document.createElement("div");
|
49
|
+
div.innerHTML = config.html;
|
50
|
+
element.parentNode.replaceChild(div.firstElementChild, element);
|
51
|
+
if (config.focusSelector) { document.querySelector(config.focusSelector).focus(); }
|
44
52
|
},
|
45
53
|
|
46
|
-
|
47
|
-
log("
|
48
|
-
|
49
|
-
|
54
|
+
setValue: function (config) {
|
55
|
+
if (CableReady.debug) { console.log("CableReady.setValue", config); }
|
56
|
+
document.querySelector(config.selector).value = config.value;
|
57
|
+
},
|
58
|
+
|
59
|
+
// Attribute Mutations ............................................................................................
|
60
|
+
|
61
|
+
setAttribute: function (config) {
|
62
|
+
if (CableReady.debug) { console.log("CableReady.setAttribute", config); }
|
63
|
+
document.querySelector(config.selector).setAttribute(config.name, config.value);
|
64
|
+
},
|
65
|
+
|
66
|
+
removeAttribute: function (config) {
|
67
|
+
if (CableReady.debug) { console.log("CableReady.removeAttribute", config); }
|
68
|
+
document.querySelector(config.selector).removeAttribute(config.name);
|
69
|
+
},
|
70
|
+
|
71
|
+
// CSS Class Mutations ............................................................................................
|
72
|
+
|
73
|
+
addCssClass: function (config) {
|
74
|
+
if (CableReady.debug) { console.log("CableReady.addCssClass", config); }
|
75
|
+
document.querySelector(config.selector).classList.add(config.name);
|
76
|
+
},
|
77
|
+
|
78
|
+
removeCssClass: function (config) {
|
79
|
+
if (CableReady.debug) { console.log("CableReady.removeCssClass", config); }
|
80
|
+
document.querySelector(config.selector).classList.remove(config.name);
|
81
|
+
},
|
82
|
+
|
83
|
+
// Dataset Mutations ..............................................................................................
|
84
|
+
|
85
|
+
setDatasetProperty: function (config) {
|
86
|
+
if (CableReady.debug) { console.log("CableReady.setDatasetProperty", config); }
|
87
|
+
document.querySelector(config.selector).dataset[config.name] = config.value;
|
50
88
|
}
|
51
89
|
};
|
52
90
|
|
@@ -57,7 +95,11 @@
|
|
57
95
|
if (operations.hasOwnProperty(name)) {
|
58
96
|
var entries = operations[name];
|
59
97
|
for (var i = 0; i < entries.length; i++) {
|
60
|
-
|
98
|
+
try {
|
99
|
+
CableReadyOperations[name](entries[i]);
|
100
|
+
} catch (e) {
|
101
|
+
console.log("CableReady detected an error! " + e.message);
|
102
|
+
}
|
61
103
|
}
|
62
104
|
}
|
63
105
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cable_ready
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Hopkins
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-09-
|
11
|
+
date: 2017-09-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 5.0.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 5.0.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|