opal-ferro 0.10.0 → 0.10.1
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 +5 -5
- data/.gitignore +1 -0
- data/.yardopts +8 -0
- data/CHANGELOG.md +23 -0
- data/README.md +29 -0
- data/docs/GettingStarted.md +187 -0
- data/lib/opal-ferro/version.rb +10 -2
- data/opal/opal-ferro/elements/ferro_combos.js.rb +130 -0
- data/opal/opal-ferro/elements/ferro_components.js.rb +82 -0
- data/opal/opal-ferro/elements/ferro_form.js.rb +257 -0
- data/opal/opal-ferro/elements/ferro_inline.js.rb +137 -0
- data/opal/opal-ferro/elements/ferro_misc.js.rb +60 -0
- data/opal/opal-ferro/ferro_base_element.js.rb +187 -0
- data/opal/opal-ferro/ferro_document.js.rb +59 -35
- data/opal/opal-ferro/ferro_elementary.js.rb +99 -63
- data/opal/opal-ferro/ferro_factory.js.rb +69 -44
- data/opal/opal-ferro/ferro_router.js.rb +147 -88
- data/opal/opal-ferro/ferro_sequence.js.rb +20 -9
- data/opal/opal-ferro/ferro_xhr.js.rb +132 -69
- data/opal/opal-ferro.rb +6 -4
- data/opal-ferro.gemspec +1 -1
- metadata +26 -7
- data/opal/opal-ferro/ferro_base_elements.js.rb +0 -158
- data/opal/opal-ferro/ferro_components.js.rb +0 -92
- data/opal/opal-ferro/ferro_element.js.rb +0 -110
- data/opal/opal-ferro/ferro_form_elements.js.rb +0 -160
@@ -1,12 +1,23 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module Ferro
|
2
|
+
# A helper class to generate unique labels.
|
3
|
+
# These labels can be used to ensure
|
4
|
+
# unique instance variable names.
|
5
|
+
class Sequence
|
6
|
+
|
7
|
+
# Create a new sequence.
|
8
|
+
#
|
9
|
+
# @param [String] prefix a prefix for generated labels
|
10
|
+
def initialize(prefix = nil)
|
11
|
+
@prefix = prefix
|
12
|
+
@next_id = 0
|
13
|
+
end
|
7
14
|
|
8
|
-
|
9
|
-
|
10
|
-
|
15
|
+
# Get the next label.
|
16
|
+
#
|
17
|
+
# @return [String] the unique label
|
18
|
+
def next
|
19
|
+
@next_id += 1
|
20
|
+
"#{@prefix}#{@next_id}"
|
21
|
+
end
|
11
22
|
end
|
12
23
|
end
|
@@ -1,82 +1,145 @@
|
|
1
|
-
|
2
|
-
require 'json'
|
3
|
-
require 'native'
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
1
|
+
module Ferro
|
2
|
+
require 'json'
|
3
|
+
require 'native'
|
4
|
+
|
5
|
+
# Create and execute AJAX requests.
|
6
|
+
# Based on turbolinks/http_request.
|
7
|
+
# Specify the url for the request and two callbacks,
|
8
|
+
# one for succesful completion of the request and one
|
9
|
+
# for a failed request.
|
10
|
+
#
|
11
|
+
# It is safe to destroy the FerroXhr instance after
|
12
|
+
# one of it's callbacks have completed.
|
13
|
+
# Note that there are no private methods in Opal. Methods that
|
14
|
+
# should be private are marked in the docs with 'Internal method'.
|
15
|
+
#
|
16
|
+
# This class can only send and receive JSON.
|
17
|
+
# For non-get requests a csrf token can be specified or left
|
18
|
+
# blank. When blank this class will try to find the token in
|
19
|
+
# the header meta data.
|
20
|
+
class Xhr
|
21
|
+
|
22
|
+
# Error message for timeouts.
|
23
|
+
TIMEOUT_FAILURE = 'Timeout'
|
24
|
+
|
25
|
+
# Start AJAX request.
|
26
|
+
#
|
27
|
+
# Valid options are:
|
28
|
+
# * :timeout (Integer) Request-timout
|
29
|
+
# * :accept (String) Header-Accept
|
30
|
+
# * :method (Symbol) Html method, default: :get
|
31
|
+
# * :csrf (String) Csrf token, if blank and method is not :get,
|
32
|
+
# meta tag 'csrf-token' will be used
|
33
|
+
# * :body (Hash) Hash of parameters to be sent
|
34
|
+
#
|
35
|
+
# @param [String] url The url for the request
|
36
|
+
# @param [Method] callback Success callback method. The callback
|
37
|
+
# method should accept one parameter [Hash] containing the
|
38
|
+
# parsed json object returned by the AJAX call
|
39
|
+
# @param [Method] error_callback Failure callback method. The callback
|
40
|
+
# method should accept two parameters [Integer, String]
|
41
|
+
# containing the status and error message
|
42
|
+
# @param [Hash] options See valid options
|
43
|
+
def initialize(url, callback, error_callback, options = {})
|
44
|
+
@url = url
|
45
|
+
@callback = callback
|
46
|
+
@error_callback = error_callback
|
47
|
+
@timeout = options[:timeout] || 5000
|
48
|
+
@accept = options[:accept] || 'application/json'
|
49
|
+
@method = (options[:method] || :get).upcase
|
50
|
+
@csrf = options[:csrf]
|
51
|
+
@body = options[:body] ? options[:body].to_json.to_s : nil
|
52
|
+
@xhr = nil
|
53
|
+
@sent = false
|
23
54
|
|
24
|
-
|
25
|
-
|
26
|
-
@xhr.JS.send
|
27
|
-
@sent = true
|
55
|
+
createXHR
|
56
|
+
send
|
28
57
|
end
|
29
|
-
end
|
30
58
|
|
31
|
-
|
32
|
-
|
33
|
-
|
59
|
+
# Internal method to start the AJAX request.
|
60
|
+
def send
|
61
|
+
if @xhr && !@sent
|
62
|
+
@xhr.JS.send(@body)
|
63
|
+
@sent = true
|
64
|
+
end
|
65
|
+
end
|
34
66
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
# `#{@xhr}.responseType = 'json'` if @accept == 'application/json'
|
40
|
-
`#{@xhr}.setRequestHeader('Accept', #{@accept})`
|
41
|
-
`#{@xhr}.setRequestHeader('Ferro-Referrer', #{@referrer})`
|
42
|
-
`#{@xhr}.addEventListener('load', function(){#{requestLoaded}})`
|
43
|
-
`#{@xhr}.addEventListener('error', function(){#{requestFailed}})`
|
44
|
-
`#{@xhr}.addEventListener('timeout', function(){#{requestTimedOut}})`
|
45
|
-
`#{@xhr}.addEventListener('abort', function(){#{requestCanceled}})`
|
46
|
-
nil
|
47
|
-
end
|
67
|
+
# Cancel a running AJAX request.
|
68
|
+
def cancel
|
69
|
+
@xhr.JS.abort if @xhr && @sent
|
70
|
+
end
|
48
71
|
|
49
|
-
|
50
|
-
|
51
|
-
|
72
|
+
# Internal method to set up the AJAX request.
|
73
|
+
def createXHR
|
74
|
+
@xhr = `new XMLHttpRequest`
|
52
75
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
76
|
+
`#{@xhr}.open(#{@method}, #{@url}, true)`
|
77
|
+
`#{@xhr}.timeout = #{@timeout}`
|
78
|
+
`#{@xhr}.setRequestHeader('Accept', #{@accept})`
|
79
|
+
|
80
|
+
if @method != 'GET'
|
81
|
+
`#{@xhr}.setRequestHeader('X-CSRF-Token', #{csrf_token})`
|
82
|
+
if @body
|
83
|
+
`#{@xhr}.setRequestHeader('Content-Type', #{@accept})`
|
84
|
+
`#{@xhr}.setRequestHeader('Content-Length', #{@body.length})`
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
`#{@xhr}.addEventListener('load', function(){#{requestLoaded}})`
|
89
|
+
`#{@xhr}.addEventListener('error', function(){#{requestFailed}})`
|
90
|
+
`#{@xhr}.addEventListener('timeout', function(){#{requestTimedOut}})`
|
91
|
+
`#{@xhr}.addEventListener('abort', function(){#{requestCanceled}})`
|
92
|
+
nil
|
62
93
|
end
|
63
94
|
|
64
|
-
|
65
|
-
|
95
|
+
# Internal method to get the csrf token from header meta data.
|
96
|
+
def csrf_token
|
97
|
+
return @csrf if @csrf
|
98
|
+
token = Native(`document.getElementsByName('csrf-token')`)
|
99
|
+
@csrf = token[0].content if token.length > 0
|
100
|
+
end
|
66
101
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
end
|
102
|
+
# Internal method to clean up the AJAX request.
|
103
|
+
def destroy
|
104
|
+
`#{@xhr} = null`
|
105
|
+
end
|
72
106
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
107
|
+
# Internal callback method, will call the success callback specified
|
108
|
+
# in initialize or the failure callback if the html return status is
|
109
|
+
# 300 or higher.
|
110
|
+
def requestLoaded
|
111
|
+
begin
|
112
|
+
status = Native(`#{@xhr}.status`)
|
113
|
+
raise if status >= 300
|
114
|
+
json = JSON.parse(`#{@xhr}.response`)
|
115
|
+
@callback.call(json)
|
116
|
+
rescue => error
|
117
|
+
@failed = true
|
118
|
+
@error_callback.call(status, error)
|
119
|
+
end
|
78
120
|
|
79
|
-
|
80
|
-
|
121
|
+
destroy
|
122
|
+
end
|
123
|
+
|
124
|
+
# Internal callback method, will call the failure callback specified
|
125
|
+
# in initialize.
|
126
|
+
def requestFailed
|
127
|
+
@failed = true
|
128
|
+
@error_callback.call(`#{@xhr}.status`, Native(`#{@xhr}.response`))
|
129
|
+
destroy
|
130
|
+
end
|
131
|
+
|
132
|
+
# Internal callback method, will call the failure callback specified
|
133
|
+
# in initialize.
|
134
|
+
def requestTimedOut
|
135
|
+
@failed = true
|
136
|
+
@error_callback.call(0, TIMEOUT_FAILURE)
|
137
|
+
destroy
|
138
|
+
end
|
139
|
+
|
140
|
+
# Internal callback method.
|
141
|
+
def requestCanceled
|
142
|
+
destroy
|
143
|
+
end
|
81
144
|
end
|
82
145
|
end
|
data/opal/opal-ferro.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
require 'opal'
|
2
2
|
require 'opal-ferro/ferro_elementary'
|
3
|
-
require 'opal-ferro/
|
3
|
+
require 'opal-ferro/ferro_base_element'
|
4
4
|
require 'opal-ferro/ferro_document'
|
5
5
|
require 'opal-ferro/ferro_factory'
|
6
6
|
require 'opal-ferro/ferro_router'
|
7
7
|
require 'opal-ferro/ferro_xhr'
|
8
8
|
require 'opal-ferro/ferro_sequence'
|
9
|
-
require 'opal-ferro/
|
10
|
-
require 'opal-ferro/
|
11
|
-
require 'opal-ferro/
|
9
|
+
require 'opal-ferro/elements/ferro_inline'
|
10
|
+
require 'opal-ferro/elements/ferro_components'
|
11
|
+
require 'opal-ferro/elements/ferro_form'
|
12
|
+
require 'opal-ferro/elements/ferro_misc'
|
13
|
+
require 'opal-ferro/elements/ferro_combos'
|
data/opal-ferro.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
|
|
21
21
|
|
22
22
|
s.add_development_dependency 'bundler', '~> 1.16'
|
23
23
|
s.add_development_dependency 'rake', '~> 10.0'
|
24
|
-
|
24
|
+
s.add_development_dependency 'yard', '~> 0.9.12'
|
25
25
|
s.add_development_dependency 'minitest', '~> 5.0'
|
26
26
|
# s.add_development_dependency 'selenium-webdriver', '~> 3.8'
|
27
27
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opal-ferro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivo Herweijer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-03-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: opal
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: yard
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.9.12
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.9.12
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: minitest
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -77,23 +91,28 @@ extra_rdoc_files: []
|
|
77
91
|
files:
|
78
92
|
- ".gitignore"
|
79
93
|
- ".travis.yml"
|
94
|
+
- ".yardopts"
|
95
|
+
- CHANGELOG.md
|
80
96
|
- CODE_OF_CONDUCT.md
|
81
97
|
- Gemfile
|
82
98
|
- LICENSE.txt
|
83
99
|
- README.md
|
84
100
|
- Rakefile
|
101
|
+
- docs/GettingStarted.md
|
85
102
|
- lib/opal-ferro.rb
|
86
103
|
- lib/opal-ferro/version.rb
|
87
104
|
- lib/opal/ferro.rb
|
88
105
|
- opal-ferro.gemspec
|
89
106
|
- opal/opal-ferro.rb
|
90
|
-
- opal/opal-ferro/
|
91
|
-
- opal/opal-ferro/ferro_components.js.rb
|
107
|
+
- opal/opal-ferro/elements/ferro_combos.js.rb
|
108
|
+
- opal/opal-ferro/elements/ferro_components.js.rb
|
109
|
+
- opal/opal-ferro/elements/ferro_form.js.rb
|
110
|
+
- opal/opal-ferro/elements/ferro_inline.js.rb
|
111
|
+
- opal/opal-ferro/elements/ferro_misc.js.rb
|
112
|
+
- opal/opal-ferro/ferro_base_element.js.rb
|
92
113
|
- opal/opal-ferro/ferro_document.js.rb
|
93
|
-
- opal/opal-ferro/ferro_element.js.rb
|
94
114
|
- opal/opal-ferro/ferro_elementary.js.rb
|
95
115
|
- opal/opal-ferro/ferro_factory.js.rb
|
96
|
-
- opal/opal-ferro/ferro_form_elements.js.rb
|
97
116
|
- opal/opal-ferro/ferro_router.js.rb
|
98
117
|
- opal/opal-ferro/ferro_sequence.js.rb
|
99
118
|
- opal/opal-ferro/ferro_xhr.js.rb
|
@@ -117,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
136
|
version: '0'
|
118
137
|
requirements: []
|
119
138
|
rubyforge_project:
|
120
|
-
rubygems_version: 2.6
|
139
|
+
rubygems_version: 2.7.6
|
121
140
|
signing_key:
|
122
141
|
specification_version: 4
|
123
142
|
summary: 'Simplifying web-development: no more html, just beautiful and simple Ruby
|
@@ -1,158 +0,0 @@
|
|
1
|
-
class FerroElementComponent < FerroElement
|
2
|
-
def component
|
3
|
-
self
|
4
|
-
end
|
5
|
-
end
|
6
|
-
|
7
|
-
# Semantical elements
|
8
|
-
class FerroElementHeader < FerroElementComponent
|
9
|
-
def _before_create
|
10
|
-
@domtype = :header
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
class FerroElementNavigation < FerroElementComponent
|
15
|
-
def _before_create
|
16
|
-
@domtype = :nav
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
class FerroElementSection < FerroElementComponent
|
21
|
-
def _before_create
|
22
|
-
@domtype = :section
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
class FerroElementArticle < FerroElementComponent
|
27
|
-
def _before_create
|
28
|
-
@domtype = :article
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
class FerroElementAside < FerroElementComponent
|
33
|
-
def _before_create
|
34
|
-
@domtype = :aside
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
class FerroElementFooter < FerroElementComponent
|
39
|
-
def _before_create
|
40
|
-
@domtype = :footer
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
FerroElementBlock = FerroElement
|
45
|
-
|
46
|
-
# Inline elements
|
47
|
-
class FerroElementText < FerroElement
|
48
|
-
def _before_create
|
49
|
-
@size = option_replace :size, 0
|
50
|
-
@domtype = @size == 0 ? :p : "h#{@size}"
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
class FerroElementList < FerroElement
|
55
|
-
def _before_create
|
56
|
-
@domtype = @options.has_key?(:type) ? :ol : :ul
|
57
|
-
@items = []
|
58
|
-
@id = FerroSequence.new 'list_'
|
59
|
-
end
|
60
|
-
|
61
|
-
def add_item(element_class, options = {})
|
62
|
-
@items << add_child(@id.next, element_class, options).sym
|
63
|
-
end
|
64
|
-
|
65
|
-
def item_count
|
66
|
-
@items.length
|
67
|
-
end
|
68
|
-
|
69
|
-
def first_item
|
70
|
-
@children[@items.first]
|
71
|
-
end
|
72
|
-
|
73
|
-
def last_item
|
74
|
-
@children[@items.last]
|
75
|
-
end
|
76
|
-
|
77
|
-
def unlist_item(sym)
|
78
|
-
@items.delete_if { |item| item == sym }
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
class FerroElementListItem < FerroElement
|
83
|
-
def _before_create
|
84
|
-
@domtype = :li
|
85
|
-
end
|
86
|
-
|
87
|
-
def destroy
|
88
|
-
super
|
89
|
-
parent.unlist_item(@sym)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
class FerroElementAnchor < FerroElement
|
94
|
-
def _before_create
|
95
|
-
@domtype = :a
|
96
|
-
@href = @options[:href]
|
97
|
-
end
|
98
|
-
|
99
|
-
def _after_create
|
100
|
-
`#{@element}.addEventListener("click",function(e){e.preventDefault();history.pushState(null,null,#{@href});#{clicked};document.activeElement.blur();})`
|
101
|
-
end
|
102
|
-
|
103
|
-
def update_href(value)
|
104
|
-
@href = value
|
105
|
-
set_attribute('href', @href)
|
106
|
-
end
|
107
|
-
|
108
|
-
def clicked
|
109
|
-
router.navigated
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
class FerroElementExternalLink < FerroElement
|
114
|
-
def _before_create
|
115
|
-
@domtype = :a
|
116
|
-
@options[:target] ||= '_blank'
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
# Miscellaneous elements
|
121
|
-
class FerroElementImage < FerroElement
|
122
|
-
|
123
|
-
# Todo use:
|
124
|
-
# <figure>
|
125
|
-
# <figcaption>
|
126
|
-
|
127
|
-
def _before_create
|
128
|
-
@domtype = :img
|
129
|
-
@options[:alt] ||= @options[:src]
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
class FerroElementCanvas < FerroElement
|
134
|
-
def _before_create
|
135
|
-
@domtype = :canvas
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
class FerroElementScript < FerroElement
|
140
|
-
def _before_create
|
141
|
-
@domtype = :script
|
142
|
-
@run = option_replace :invoke, true
|
143
|
-
end
|
144
|
-
|
145
|
-
def _after_create
|
146
|
-
load
|
147
|
-
invoke if @run
|
148
|
-
end
|
149
|
-
|
150
|
-
def load;end
|
151
|
-
def invoke;end
|
152
|
-
end
|
153
|
-
|
154
|
-
class FerroElementVar < FerroElement
|
155
|
-
def _before_create
|
156
|
-
@domtype = option_replace :domtype, :div
|
157
|
-
end
|
158
|
-
end
|
@@ -1,92 +0,0 @@
|
|
1
|
-
# A component with a text entry field and submit button
|
2
|
-
class FerroFormSearch < FerroForm
|
3
|
-
|
4
|
-
def _before_create
|
5
|
-
@button_text = option_replace :button_text, ' '
|
6
|
-
@placeholder = option_replace :placeholder, ' Search...'
|
7
|
-
end
|
8
|
-
|
9
|
-
def cascade
|
10
|
-
add_child :entry, FerroFormSearchInput, { placeholder: @placeholder }
|
11
|
-
add_child :submit, FerroFormSearchSubmit, { content: @button_text }
|
12
|
-
end
|
13
|
-
|
14
|
-
def do_submit
|
15
|
-
value = entry.value.strip
|
16
|
-
submitted(value) if !value.empty?
|
17
|
-
|
18
|
-
entry.toggle_state :search_input_open
|
19
|
-
submit.toggle_state :search_submit_open
|
20
|
-
|
21
|
-
entry.value = nil
|
22
|
-
entry.set_focus if entry.state_active?(:search_input_open)
|
23
|
-
end
|
24
|
-
|
25
|
-
def submitted(value);end
|
26
|
-
end
|
27
|
-
|
28
|
-
class FerroFormSearchInput < FerroFormInput
|
29
|
-
|
30
|
-
def _after_create
|
31
|
-
add_state :search_input_open
|
32
|
-
super
|
33
|
-
end
|
34
|
-
|
35
|
-
def entered
|
36
|
-
parent.do_submit
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
class FerroFormSearchSubmit < FerroFormButton
|
41
|
-
|
42
|
-
def _after_create
|
43
|
-
add_state :search_submit_open
|
44
|
-
super
|
45
|
-
end
|
46
|
-
|
47
|
-
def clicked
|
48
|
-
parent.do_submit
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# A simple pull-down menu
|
53
|
-
# @option[items]: a list of classes
|
54
|
-
class FerroPullDown < FerroElementBlock
|
55
|
-
|
56
|
-
def _before_create
|
57
|
-
@title_text = option_replace :title, '='
|
58
|
-
@items = option_replace :items, []
|
59
|
-
super
|
60
|
-
end
|
61
|
-
|
62
|
-
def _after_create
|
63
|
-
add_state :pull_down_open
|
64
|
-
super
|
65
|
-
end
|
66
|
-
|
67
|
-
def cascade
|
68
|
-
add_child :title, FerroPullDownTitle, { content: @title_text }
|
69
|
-
add_child :items, FerroPullDownItems, { items: @items }
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
class FerroPullDownTitle < FerroFormBlock
|
74
|
-
def clicked
|
75
|
-
parent.toggle_state :pull_down_open
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
class FerroPullDownItems < FerroElementBlock
|
80
|
-
|
81
|
-
def _before_create
|
82
|
-
@id = FerroSequence.new 'pdi_'
|
83
|
-
@itemlist = option_replace :items, []
|
84
|
-
super
|
85
|
-
end
|
86
|
-
|
87
|
-
def cascade
|
88
|
-
@items = @itemlist.map do |item|
|
89
|
-
add_child @id.next, item
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|