pwnstyles_rails 0.1.8 → 0.1.9
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.
- data/VERSION +1 -1
- data/app/assets/javascripts/pwn-fx.js.coffee +135 -47
- data/lib/pwnstyles_rails/generators/layouts/_status_bar.html.erb +2 -2
- data/pwnstyles_rails.gemspec +2 -2
- metadata +17 -17
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.9
|
@@ -18,7 +18,7 @@ class PwnFxClass
|
|
18
18
|
|
19
19
|
# Wires JS to elements with data-pwnfx attributes.
|
20
20
|
#
|
21
|
-
# @param
|
21
|
+
# @param {Element} root the element whose content is wired; use document at
|
22
22
|
# load time
|
23
23
|
wire: (root) ->
|
24
24
|
for effect in @effects
|
@@ -38,19 +38,19 @@ class PwnFxClass
|
|
38
38
|
|
39
39
|
# Registers a PwnFx effect.
|
40
40
|
#
|
41
|
-
# @param
|
41
|
+
# @param {String} attrName string following data-pwnfx- in the effect's
|
42
42
|
# attribute names
|
43
43
|
# @param klass the class that wraps the effect's implementation
|
44
44
|
registerEffect: (attrPrefix, klass) ->
|
45
45
|
if @effectsByName[attrPrefix]
|
46
|
-
throw new Error("
|
46
|
+
throw new Error("PwnFx effect name {attrPrefix} already registered")
|
47
47
|
@effects.push [attrPrefix, klass]
|
48
48
|
|
49
49
|
# Finds a scoping container.
|
50
50
|
#
|
51
|
-
# @param
|
52
|
-
# @param
|
53
|
-
# @return
|
51
|
+
# @param {String} scopeId the scope ID to look for
|
52
|
+
# @param {HTMLElement} element the element where the lookup starts
|
53
|
+
# @return {HTMLElement} the closest parent of the given element whose
|
54
54
|
# data-pwnfx-scope matches the scopeId argument; window.document is
|
55
55
|
# returned if no such element exists or if scope is null
|
56
56
|
resolveScope: (scopeId, element) ->
|
@@ -61,9 +61,9 @@ class PwnFxClass
|
|
61
61
|
|
62
62
|
# Performs a scoped querySelectAll.
|
63
63
|
#
|
64
|
-
# @param
|
65
|
-
# @param
|
66
|
-
# @return
|
64
|
+
# @param {HTMLElement} scope the DOM element serving as the search scope
|
65
|
+
# @param {String} selector the CSS selector to query
|
66
|
+
# @return {NodeList, Array} the elements in the scope that match the CSS
|
67
67
|
# selector; the scope container can belong to the returned array
|
68
68
|
queryScope: (scope, selector) ->
|
69
69
|
scopeMatches = false
|
@@ -85,6 +85,64 @@ class PwnFxClass
|
|
85
85
|
else
|
86
86
|
scope.querySelectorAll selector
|
87
87
|
|
88
|
+
# Executes the JavaScript inside the <script> tags in a DOM subtree.
|
89
|
+
#
|
90
|
+
# @param {HTMLElement} element the DOM element rooting the subtree that will
|
91
|
+
# be searched for <script> tags
|
92
|
+
runScripts: (element) ->
|
93
|
+
# HACK: <script>s are removed and re-inserted so the browser runs them
|
94
|
+
for scriptElement in element.querySelectorAll('script')
|
95
|
+
parent = scriptElement.parentElement
|
96
|
+
nextSibling = scriptElement.nextSibling
|
97
|
+
parent.removeChild scriptElement
|
98
|
+
parent.insertBefore scriptElement.cloneNode(true), nextSibling
|
99
|
+
null
|
100
|
+
|
101
|
+
# Replaces an element's contents with some HTML.
|
102
|
+
#
|
103
|
+
# The JavaScript inside the HTML's <script> tags will be executed.
|
104
|
+
#
|
105
|
+
# @param {HTMLElement} element the element whose contents will be replaced
|
106
|
+
# @param {String}
|
107
|
+
replaceHtml: (element, html) ->
|
108
|
+
element.innerHTML = html
|
109
|
+
@runScripts element
|
110
|
+
@wire element
|
111
|
+
|
112
|
+
# The closest form element wrapping a node.
|
113
|
+
#
|
114
|
+
# @param {HTMLElement} element the element whose parent chain will be searched
|
115
|
+
# @return {HTMLFormElement} the element's closest parent form, or null if the
|
116
|
+
# element is not wrapped in a <form>
|
117
|
+
parentForm: (element) ->
|
118
|
+
while element
|
119
|
+
return element if element.nodeName == 'FORM'
|
120
|
+
element = element.parentNode
|
121
|
+
null
|
122
|
+
|
123
|
+
# Do AJAX.
|
124
|
+
#
|
125
|
+
# @param {String} url the request URL (e.g., "http://localhost/path/to.html")
|
126
|
+
# @param {String} method the request method (e.g., "POST")
|
127
|
+
# @param [HTMLFormElement] form the DOM form whose data will be submitted
|
128
|
+
# @param [function(data)] onData callback that receives the XHR data, if the
|
129
|
+
# XHR completes successfully
|
130
|
+
xhr: (url, method, form, onData) ->
|
131
|
+
xhr = new XMLHttpRequest
|
132
|
+
xhr.onload = @_xhr_onload
|
133
|
+
xhr.pwnfxOnData = onData
|
134
|
+
xhr.open method, url
|
135
|
+
xhr.setRequestHeader 'X-Requested-With', 'XMLHttpRequest'
|
136
|
+
if form
|
137
|
+
xhr.send new FormData(form)
|
138
|
+
else
|
139
|
+
xhr.send null
|
140
|
+
|
141
|
+
# Called when an XHR request issued by PwnFx.xhr works out.
|
142
|
+
_xhr_onload: ->
|
143
|
+
if @status < 200 || @status >= 300
|
144
|
+
throw new Error("XHR result ignored due to HTTP status: #{@statusText}")
|
145
|
+
@pwnfxOnData @responseText
|
88
146
|
|
89
147
|
# Singleton instance.
|
90
148
|
PwnFx = new PwnFxClass
|
@@ -96,11 +154,24 @@ PwnFx = new PwnFxClass
|
|
96
154
|
# data-pwnfx-move: an identifier connecting the move's target element
|
97
155
|
# data-pwnfx-move-target: set to the same value as data-pwnfx-move on the
|
98
156
|
# element that will receive the moved element as its last child
|
157
|
+
# data-pwnfx-move-method: 'append' adds the moved as the element as the
|
158
|
+
# target's last child, 'replace' clears the target element, then adds the
|
159
|
+
# moved element as the target's only child
|
99
160
|
class PwnFxMove
|
100
161
|
constructor: (element, identifier, scopeId) ->
|
101
162
|
scope = PwnFx.resolveScope scopeId, element
|
163
|
+
method = element.getAttribute('data-pwnfx-move-method') || 'append'
|
102
164
|
target = document.querySelector "[data-pwnfx-move-target=\"#{identifier}\"]"
|
103
|
-
|
165
|
+
|
166
|
+
switch method
|
167
|
+
when 'append'
|
168
|
+
target.appendChild element
|
169
|
+
when 'replace'
|
170
|
+
target.innerHTML = ''
|
171
|
+
target.appendChild element
|
172
|
+
else
|
173
|
+
throw new Error("pwnfx-move-method #{method} not implemented")
|
174
|
+
|
104
175
|
|
105
176
|
PwnFx.registerEffect 'move', PwnFxMove
|
106
177
|
|
@@ -146,68 +217,85 @@ class PwnFxRender
|
|
146
217
|
PwnFx.registerEffect 'render', PwnFxRender
|
147
218
|
|
148
219
|
|
220
|
+
# Loads some content after the main page load via an AJAX request.
|
221
|
+
#
|
222
|
+
# The text / HTML returned by the request is placed in another element. Scripts
|
223
|
+
# in <script> tags are executed.
|
224
|
+
#
|
225
|
+
# Element attributes:
|
226
|
+
# data-pwnfx-delayed: identifier connecting the AJAX data receiver
|
227
|
+
# data-pwnfx-delayed-url: URL to perform an AJAX request to
|
228
|
+
# data-pwnfx-delayed-method: the HTTP method of AJAX request (default: POST)
|
229
|
+
# data-pwnfx-delayed-ms: the delay between the page load and the issuing of
|
230
|
+
# the AJAX request (default: 1000ms)
|
231
|
+
# data-pwnfx-delayed-target: set to the value of data-pwnfx-delayed on the
|
232
|
+
# element populated with the AJAX response
|
233
|
+
class PwnFxDelayed
|
234
|
+
constructor: (element, identifier, scopeId) ->
|
235
|
+
targetSelector = "[data-pwnfx-delayed-target=\"#{identifier}\"]"
|
236
|
+
xhrUrl = element.getAttribute('data-pwnfx-delayed-url')
|
237
|
+
xhrMethod = element.getAttribute('data-pwnfx-delayed-method') || 'POST'
|
238
|
+
xhrForm = PwnFx.parentForm element
|
239
|
+
delay = parseInt(
|
240
|
+
element.getAttribute('data-pwnfx-delayed-ms') || '1000');
|
241
|
+
|
242
|
+
ajaxLoad = ->
|
243
|
+
PwnFx.xhr xhrUrl, xhrMethod, xhrForm, (data) ->
|
244
|
+
scope = PwnFx.resolveScope scopeId, element
|
245
|
+
for targetElement in PwnFx.queryScope(scope, targetSelector)
|
246
|
+
PwnFx.replaceHtml targetElement, data
|
247
|
+
|
248
|
+
window.setTimeout ajaxLoad, delay
|
249
|
+
|
250
|
+
PwnFx.registerEffect 'delayed', PwnFxDelayed
|
251
|
+
|
252
|
+
|
149
253
|
# Fires off an AJAX request (almost) every time when an element changes.
|
150
254
|
#
|
151
|
-
# The text / HTML returned by the request is placed in another element.
|
255
|
+
# The text / HTML returned by the request is placed in another element. Scripts
|
256
|
+
# in <script> tags are executed.
|
152
257
|
#
|
153
258
|
# Element attributes:
|
154
|
-
# data-pwnfx-refresh:
|
259
|
+
# data-pwnfx-refresh: identifier connecting the AJAX data receiver
|
260
|
+
# data-pwnfx-refresh-url: URL to perform an AJAX request to
|
155
261
|
# data-pwnfx-refresh-method: the HTTP method of AJAX request (default: POST)
|
156
|
-
# data-pwnfx-refresh-ms:
|
262
|
+
# data-pwnfx-refresh-ms: delay between a change on the source element and
|
157
263
|
# AJAX refresh requests (default: 200ms)
|
158
|
-
# data-pwnfx-target: the
|
264
|
+
# data-pwnfx-refresh-target: set to the value of data-pwnfx-refresh on the
|
265
|
+
# element populated with the AJAX response
|
159
266
|
class PwnFxRefresh
|
160
|
-
constructor: (element,
|
161
|
-
targetSelector =
|
162
|
-
|
163
|
-
element.getAttribute('data-pwnfx-refresh-ms') || '200');
|
267
|
+
constructor: (element, identifier, scopeId) ->
|
268
|
+
targetSelector = "[data-pwnfx-refresh-target=\"#{identifier}\"]"
|
269
|
+
xhrUrl = element.getAttribute('data-pwnfx-refresh-url')
|
164
270
|
xhrMethod = element.getAttribute('data-pwnfx-refresh-method') || 'POST'
|
165
|
-
xhrForm =
|
271
|
+
xhrForm = PwnFx.parentForm element
|
272
|
+
refreshDelay = parseInt(
|
273
|
+
element.getAttribute('data-pwnfx-refresh-ms') || '200');
|
166
274
|
|
167
|
-
|
168
|
-
data = @responseText
|
275
|
+
onXhrData = (data) ->
|
169
276
|
scope = PwnFx.resolveScope scopeId, element
|
170
277
|
for targetElement in PwnFx.queryScope(scope, targetSelector)
|
171
|
-
|
172
|
-
# HACK: <script>s are removed and re-inserted so the browser runs them
|
173
|
-
for scriptElement in targetElement.querySelectorAll('script')
|
174
|
-
parent = scriptElement.parentElement
|
175
|
-
nextSibling = scriptElement.nextSibling
|
176
|
-
parent.removeChild scriptElement
|
177
|
-
parent.insertBefore scriptElement.cloneNode(true), nextSibling
|
178
|
-
PwnFx.wire targetElement
|
278
|
+
PwnFx.replaceHtml targetElement, data
|
179
279
|
|
180
|
-
|
280
|
+
changeTimeout = null
|
181
281
|
refreshOldValue = null
|
182
282
|
ajaxRefresh = ->
|
183
|
-
|
184
|
-
xhr
|
185
|
-
xhr.onload = onXhrSuccess
|
186
|
-
xhr.open xhrMethod, xhrUrl
|
187
|
-
xhr.send new FormData(xhrForm)
|
283
|
+
changeTimeout = null
|
284
|
+
PwnFx.xhr xhrUrl, xhrMethod, xhrForm, onXhrData
|
188
285
|
|
189
286
|
onChange = ->
|
190
287
|
value = element.value
|
191
288
|
return true if value == refreshOldValue
|
192
289
|
refreshOldValue = value
|
193
290
|
|
194
|
-
|
195
|
-
|
196
|
-
window.setTimeout ajaxRefresh, refreshInterval
|
291
|
+
window.clearTimeout changeTimeout if changeTimeout != null
|
292
|
+
changeTimeout = window.setTimeout ajaxRefresh, refreshDelay
|
197
293
|
true
|
198
294
|
|
199
295
|
element.addEventListener 'change', onChange, false
|
200
296
|
element.addEventListener 'keydown', onChange, false
|
201
297
|
element.addEventListener 'keyup', onChange, false
|
202
298
|
|
203
|
-
|
204
|
-
# The closest form element wrapping a node.
|
205
|
-
parentForm: (element) ->
|
206
|
-
while element
|
207
|
-
return element if element.nodeName == 'FORM'
|
208
|
-
element = element.parentNode
|
209
|
-
null
|
210
|
-
|
211
299
|
PwnFx.registerEffect 'refresh', PwnFxRefresh
|
212
300
|
|
213
301
|
|
@@ -300,7 +388,7 @@ class PwnFxHide
|
|
300
388
|
element.addEventListener 'change', onChange, false
|
301
389
|
onChange()
|
302
390
|
else
|
303
|
-
throw new Error("Unimplemented trigger #{trigger}")
|
391
|
+
throw new Error("Unimplemented pwnfx-hide trigger #{trigger}")
|
304
392
|
|
305
393
|
PwnFx.registerEffect 'hide', PwnFxHide
|
306
394
|
|
data/pwnstyles_rails.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "pwnstyles_rails"
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.9"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Victor Costan"]
|
12
|
-
s.date = "2012-02-
|
12
|
+
s.date = "2012-02-08"
|
13
13
|
s.description = "Included CSS was designed for reuse across pwnb.us apps."
|
14
14
|
s.email = "victor@costan.us"
|
15
15
|
s.extra_rdoc_files = [
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pwnstyles_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.9
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-02-
|
12
|
+
date: 2012-02-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
16
|
-
requirement: &
|
16
|
+
requirement: &11333680 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 3.2.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *11333680
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: sass-rails
|
27
|
-
requirement: &
|
27
|
+
requirement: &11332740 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 3.2.4
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *11332740
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: shoulda
|
38
|
-
requirement: &
|
38
|
+
requirement: &11331580 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *11331580
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: bundler
|
49
|
-
requirement: &
|
49
|
+
requirement: &11330960 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 1.0.0
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *11330960
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: jeweler
|
60
|
-
requirement: &
|
60
|
+
requirement: &11330260 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: 1.8.0
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *11330260
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rcov
|
71
|
-
requirement: &
|
71
|
+
requirement: &11329560 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *11329560
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: simplecov
|
82
|
-
requirement: &
|
82
|
+
requirement: &11328840 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *11328840
|
91
91
|
description: Included CSS was designed for reuse across pwnb.us apps.
|
92
92
|
email: victor@costan.us
|
93
93
|
executables: []
|
@@ -152,7 +152,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
152
152
|
version: '0'
|
153
153
|
segments:
|
154
154
|
- 0
|
155
|
-
hash: -
|
155
|
+
hash: -1561629047696915926
|
156
156
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
157
|
none: false
|
158
158
|
requirements:
|