turbograft 0.4.8 → 0.5.0

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.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -4
  3. data/lib/assets/javascripts/turbograft/click.js +44 -0
  4. data/lib/assets/javascripts/turbograft/component_url.js +53 -0
  5. data/lib/assets/javascripts/turbograft/csrf_token.js +23 -0
  6. data/lib/assets/javascripts/turbograft/document.js +20 -0
  7. data/lib/assets/javascripts/turbograft/initializers.js +83 -0
  8. data/lib/assets/javascripts/turbograft/link.js +58 -0
  9. data/lib/assets/javascripts/turbograft/page.js +105 -0
  10. data/lib/assets/javascripts/turbograft/remote.js +248 -0
  11. data/lib/assets/javascripts/turbograft/response.js +48 -0
  12. data/lib/assets/javascripts/turbograft/turbohead.js +159 -0
  13. data/lib/assets/javascripts/turbograft/turbolinks.js +504 -0
  14. data/lib/assets/javascripts/turbograft.js +37 -0
  15. data/lib/turbograft/version.rb +1 -1
  16. metadata +27 -27
  17. data/lib/assets/javascripts/turbograft/click.coffee +0 -34
  18. data/lib/assets/javascripts/turbograft/component_url.coffee +0 -24
  19. data/lib/assets/javascripts/turbograft/csrf_token.coffee +0 -9
  20. data/lib/assets/javascripts/turbograft/document.coffee +0 -11
  21. data/lib/assets/javascripts/turbograft/initializers.coffee +0 -67
  22. data/lib/assets/javascripts/turbograft/link.coffee +0 -41
  23. data/lib/assets/javascripts/turbograft/page.coffee +0 -77
  24. data/lib/assets/javascripts/turbograft/remote.coffee +0 -179
  25. data/lib/assets/javascripts/turbograft/response.coffee +0 -31
  26. data/lib/assets/javascripts/turbograft/turbohead.coffee +0 -142
  27. data/lib/assets/javascripts/turbograft/turbolinks.coffee +0 -361
  28. data/lib/assets/javascripts/turbograft.coffee +0 -30
@@ -0,0 +1,37 @@
1
+ //= require_self
2
+ //= require_tree ./turbograft
3
+
4
+ if (window.TurboGraft == null) { window.TurboGraft = { handlers: {} }; }
5
+
6
+ TurboGraft.tgAttribute = function(attr) {
7
+ if (attr.slice(0, 3) === 'tg-') {
8
+ return `data-${attr}`;
9
+ } else {
10
+ return `data-tg-${attr}`;
11
+ }
12
+ };
13
+
14
+ TurboGraft.getTGAttribute = function(node, attr) {
15
+ const tgAttr = TurboGraft.tgAttribute(attr);
16
+ return node.getAttribute(tgAttr) || node.getAttribute(attr);
17
+ };
18
+
19
+ TurboGraft.removeTGAttribute = function(node, attr) {
20
+ const tgAttr = TurboGraft.tgAttribute(attr);
21
+ node.removeAttribute(tgAttr);
22
+ node.removeAttribute(attr);
23
+ };
24
+
25
+ TurboGraft.hasTGAttribute = function(node, attr) {
26
+ const tgAttr = TurboGraft.tgAttribute(attr);
27
+ return node.hasAttribute(tgAttr) || node.hasAttribute(attr);
28
+ };
29
+
30
+ TurboGraft.querySelectorAllTGAttribute = function(node, attr, value = null) {
31
+ const tgAttr = TurboGraft.tgAttribute(attr);
32
+ if (value) {
33
+ return node.querySelectorAll(`[${tgAttr}=${value}], [${attr}=${value}]`);
34
+ } else {
35
+ return node.querySelectorAll(`[${tgAttr}], [${attr}]`);
36
+ }
37
+ };
@@ -1,3 +1,3 @@
1
1
  module TurboGraft
2
- VERSION = '0.4.8'
2
+ VERSION = '0.5.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: turbograft
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.8
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kristian Plettenberg-Dussault
@@ -15,16 +15,16 @@ authors:
15
15
  autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
- date: 2021-03-19 00:00:00.000000000 Z
18
+ date: 2023-09-14 00:00:00.000000000 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- name: coffee-rails
21
+ name: bundler
22
22
  requirement: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- type: :runtime
27
+ type: :development
28
28
  prerelease: false
29
29
  version_requirements: !ruby/object:Gem::Requirement
30
30
  requirements:
@@ -32,7 +32,7 @@ dependencies:
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  - !ruby/object:Gem::Dependency
35
- name: bundler
35
+ name: rake
36
36
  requirement: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
@@ -46,7 +46,7 @@ dependencies:
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  - !ruby/object:Gem::Dependency
49
- name: rake
49
+ name: rails
50
50
  requirement: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
@@ -60,7 +60,7 @@ dependencies:
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  - !ruby/object:Gem::Dependency
63
- name: rails
63
+ name: jquery-rails
64
64
  requirement: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
@@ -74,7 +74,7 @@ dependencies:
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  - !ruby/object:Gem::Dependency
77
- name: jquery-rails
77
+ name: minitest-reporters
78
78
  requirement: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - ">="
@@ -88,7 +88,7 @@ dependencies:
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  - !ruby/object:Gem::Dependency
91
- name: minitest-reporters
91
+ name: capybara
92
92
  requirement: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - ">="
@@ -102,7 +102,7 @@ dependencies:
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  - !ruby/object:Gem::Dependency
105
- name: capybara
105
+ name: selenium-webdriver
106
106
  requirement: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - ">="
@@ -116,7 +116,7 @@ dependencies:
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0'
118
118
  - !ruby/object:Gem::Dependency
119
- name: selenium-webdriver
119
+ name: teaspoon-mocha
120
120
  requirement: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - ">="
@@ -130,7 +130,7 @@ dependencies:
130
130
  - !ruby/object:Gem::Version
131
131
  version: '0'
132
132
  - !ruby/object:Gem::Dependency
133
- name: teaspoon-mocha
133
+ name: sqlite3
134
134
  requirement: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - ">="
@@ -144,7 +144,7 @@ dependencies:
144
144
  - !ruby/object:Gem::Version
145
145
  version: '0'
146
146
  - !ruby/object:Gem::Dependency
147
- name: sqlite3
147
+ name: thin
148
148
  requirement: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - ">="
@@ -158,7 +158,7 @@ dependencies:
158
158
  - !ruby/object:Gem::Version
159
159
  version: '0'
160
160
  - !ruby/object:Gem::Dependency
161
- name: thin
161
+ name: webrick
162
162
  requirement: !ruby/object:Gem::Requirement
163
163
  requirements:
164
164
  - - ">="
@@ -224,18 +224,18 @@ extra_rdoc_files: []
224
224
  files:
225
225
  - MIT-LICENSE
226
226
  - README.md
227
- - lib/assets/javascripts/turbograft.coffee
228
- - lib/assets/javascripts/turbograft/click.coffee
229
- - lib/assets/javascripts/turbograft/component_url.coffee
230
- - lib/assets/javascripts/turbograft/csrf_token.coffee
231
- - lib/assets/javascripts/turbograft/document.coffee
232
- - lib/assets/javascripts/turbograft/initializers.coffee
233
- - lib/assets/javascripts/turbograft/link.coffee
234
- - lib/assets/javascripts/turbograft/page.coffee
235
- - lib/assets/javascripts/turbograft/remote.coffee
236
- - lib/assets/javascripts/turbograft/response.coffee
237
- - lib/assets/javascripts/turbograft/turbohead.coffee
238
- - lib/assets/javascripts/turbograft/turbolinks.coffee
227
+ - lib/assets/javascripts/turbograft.js
228
+ - lib/assets/javascripts/turbograft/click.js
229
+ - lib/assets/javascripts/turbograft/component_url.js
230
+ - lib/assets/javascripts/turbograft/csrf_token.js
231
+ - lib/assets/javascripts/turbograft/document.js
232
+ - lib/assets/javascripts/turbograft/initializers.js
233
+ - lib/assets/javascripts/turbograft/link.js
234
+ - lib/assets/javascripts/turbograft/page.js
235
+ - lib/assets/javascripts/turbograft/remote.js
236
+ - lib/assets/javascripts/turbograft/response.js
237
+ - lib/assets/javascripts/turbograft/turbohead.js
238
+ - lib/assets/javascripts/turbograft/turbolinks.js
239
239
  - lib/turbograft.rb
240
240
  - lib/turbograft/cookies.rb
241
241
  - lib/turbograft/redirection.rb
@@ -263,7 +263,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
263
263
  - !ruby/object:Gem::Version
264
264
  version: '0'
265
265
  requirements: []
266
- rubygems_version: 3.0.3
266
+ rubygems_version: 3.4.19
267
267
  signing_key:
268
268
  specification_version: 4
269
269
  summary: turbolinks with partial page replacement
@@ -1,34 +0,0 @@
1
- # The Click class handles clicked links, verifying if Turbolinks should
2
- # take control by inspecting both the event and the link. If it should,
3
- # the page change process is initiated. If not, control is passed back
4
- # to the browser for default functionality.
5
- class window.Click
6
- @installHandlerLast: (event) ->
7
- unless event.defaultPrevented
8
- document.removeEventListener 'click', Click.handle, false
9
- document.addEventListener 'click', Click.handle, false
10
-
11
- @handle: (event) ->
12
- new Click event
13
-
14
- constructor: (@event) ->
15
- return if @event.defaultPrevented
16
- @_extractLink()
17
- if @_validForTurbolinks()
18
- Turbolinks.visit @link.href
19
- @event.preventDefault()
20
-
21
- _extractLink: ->
22
- link = @event.target
23
- link = link.parentNode until !link.parentNode or link.nodeName is 'A'
24
- @link = new Link(link) if link.nodeName is 'A' and link.href.length isnt 0
25
-
26
- _validForTurbolinks: ->
27
- @link? and not (@link.shouldIgnore() or @_nonStandardClick())
28
-
29
- _nonStandardClick: ->
30
- @event.which > 1 or
31
- @event.metaKey or
32
- @event.ctrlKey or
33
- @event.shiftKey or
34
- @event.altKey
@@ -1,24 +0,0 @@
1
- # The ComponentUrl class converts a basic URL string into an object
2
- # that behaves similarly to document.location.
3
- #
4
- # If an instance is created from a relative URL, the current document
5
- # is used to fill in the missing attributes (protocol, host, port).
6
- class window.ComponentUrl
7
- constructor: (@original = document.location.href) ->
8
- return @original if @original.constructor is ComponentUrl
9
- @_parse()
10
-
11
- withoutHash: -> @href.replace @hash, ''
12
-
13
- # Intention revealing function alias
14
- withoutHashForIE10compatibility: -> @withoutHash()
15
-
16
- hasNoHash: -> @hash.length is 0
17
-
18
- _parse: ->
19
- (@link ?= document.createElement 'a').href = @original
20
- { @href, @protocol, @host, @hostname, @port, @pathname, @search, @hash } = @link
21
- @origin = [@protocol, '//', @hostname].join ''
22
- @origin += ":#{@port}" unless @port.length is 0
23
- @relative = [@pathname, @search, @hash].join ''
24
- @absolute = @href
@@ -1,9 +0,0 @@
1
- class window.CSRFToken
2
- @get: (doc = document) ->
3
- node: tag = doc.querySelector 'meta[name="csrf-token"]'
4
- token: tag?.getAttribute? 'content'
5
-
6
- @update: (latest) ->
7
- current = @get()
8
- if current.token? and latest? and current.token isnt latest
9
- current.node.setAttribute 'content', latest
@@ -1,11 +0,0 @@
1
- TurboGraft.Document =
2
- create: (html) ->
3
- if /<(html|body)/i.test(html)
4
- doc = document.documentElement.cloneNode()
5
- doc.innerHTML = html
6
- else
7
- doc = document.documentElement.cloneNode(true)
8
- doc.querySelector('body').innerHTML = html
9
- doc.head = doc.querySelector('head')
10
- doc.body = doc.querySelector('body')
11
- doc
@@ -1,67 +0,0 @@
1
- hasClass = (node, search) ->
2
- node.classList.contains(search)
3
-
4
- nodeIsDisabled = (node) ->
5
- node.getAttribute('disabled') || hasClass(node, 'disabled')
6
-
7
- setupRemoteFromTarget = (target, httpRequestType, form = null) ->
8
- httpUrl = target.getAttribute('href') || target.getAttribute('action')
9
-
10
- throw new Error("Turbograft developer error: You did not provide a URL ('#{urlAttribute}' attribute) for data-tg-remote") unless httpUrl
11
-
12
- if TurboGraft.getTGAttribute(target, "remote-once")
13
- TurboGraft.removeTGAttribute(target, "remote-once")
14
- TurboGraft.removeTGAttribute(target, "tg-remote")
15
-
16
- options =
17
- httpRequestType: httpRequestType
18
- httpUrl: httpUrl
19
- fullRefresh: TurboGraft.getTGAttribute(target, 'full-refresh')?
20
- refreshOnSuccess: TurboGraft.getTGAttribute(target, 'refresh-on-success')
21
- refreshOnSuccessExcept: TurboGraft.getTGAttribute(target, 'full-refresh-on-success-except')
22
- refreshOnError: TurboGraft.getTGAttribute(target, 'refresh-on-error')
23
- refreshOnErrorExcept: TurboGraft.getTGAttribute(target, 'full-refresh-on-error-except')
24
-
25
- new TurboGraft.Remote(options, form, target)
26
-
27
- TurboGraft.handlers.remoteMethodHandler = (ev) ->
28
- target = ev.clickTarget
29
- httpRequestType = TurboGraft.getTGAttribute(target, 'tg-remote')
30
-
31
- return unless httpRequestType
32
- ev.preventDefault()
33
-
34
- remote = setupRemoteFromTarget(target, httpRequestType)
35
- remote.submit()
36
- return
37
-
38
- TurboGraft.handlers.remoteFormHandler = (ev) ->
39
- target = ev.target
40
- method = target.getAttribute('method')
41
-
42
- return unless TurboGraft.hasTGAttribute(target, 'tg-remote')
43
- ev.preventDefault()
44
-
45
- remote = setupRemoteFromTarget(target, method, target)
46
- remote.submit()
47
- return
48
-
49
- documentListenerForButtons = (eventType, handler, useCapture = false) ->
50
- document.addEventListener eventType, (ev) ->
51
- target = ev.target
52
-
53
- while target != document && target?
54
- if target.nodeName == "A" || target.nodeName == "BUTTON"
55
- isNodeDisabled = nodeIsDisabled(target)
56
- ev.preventDefault() if isNodeDisabled
57
- unless isNodeDisabled
58
- ev.clickTarget = target
59
- handler(ev)
60
- return
61
-
62
- target = target.parentNode
63
-
64
- documentListenerForButtons('click', TurboGraft.handlers.remoteMethodHandler, true)
65
-
66
- document.addEventListener "submit", (ev) ->
67
- TurboGraft.handlers.remoteFormHandler(ev)
@@ -1,41 +0,0 @@
1
- # The Link class derives from the ComponentUrl class, but is built from an
2
- # existing link element. Provides verification functionality for Turbolinks
3
- # to use in determining whether it should process the link when clicked.
4
- class window.Link extends ComponentUrl
5
- @HTML_EXTENSIONS: ['html']
6
-
7
- @allowExtensions: (extensions...) ->
8
- Link.HTML_EXTENSIONS.push extension for extension in extensions
9
- Link.HTML_EXTENSIONS
10
-
11
- constructor: (@link) ->
12
- return @link if @link.constructor is Link
13
- @original = @link.href
14
- super
15
-
16
- shouldIgnore: ->
17
- @_crossOrigin() or
18
- @_anchored() or
19
- @_nonHtml() or
20
- @_optOut() or
21
- @_target()
22
-
23
- _crossOrigin: ->
24
- @origin isnt (new ComponentUrl).origin
25
-
26
- _anchored: ->
27
- ((@hash and @withoutHash()) is (current = new ComponentUrl).withoutHash()) or
28
- (@href is current.href + '#')
29
-
30
- _nonHtml: ->
31
- @pathname.match(/\.[a-z]+$/g) and not @pathname.match(new RegExp("\\.(?:#{Link.HTML_EXTENSIONS.join('|')})?$", 'g'))
32
-
33
- _optOut: ->
34
- link = @link
35
- until ignore or link is document or link is null
36
- ignore = link.getAttribute('data-no-turbolink')?
37
- link = link.parentNode
38
- ignore
39
-
40
- _target: ->
41
- @link.target.length isnt 0
@@ -1,77 +0,0 @@
1
- window.Page = {} if !window.Page
2
-
3
- Page.visit = (url, opts={}) ->
4
- if opts.reload
5
- window.location = url
6
- else
7
- Turbolinks.visit(url)
8
-
9
- Page.refresh = (options = {}, callback) ->
10
- newUrl = if options.url
11
- options.url
12
- else if options.queryParams
13
- paramString = $.param(options.queryParams)
14
- paramString = "?#{paramString}" if paramString
15
- location.pathname + paramString
16
- else
17
- location.href
18
-
19
- turboOptions = {
20
- partialReplace: true,
21
- exceptKeys: options.exceptKeys,
22
- onlyKeys: options.onlyKeys,
23
- updatePushState: options.updatePushState,
24
- callback: callback
25
- }
26
-
27
- if xhr = options.response
28
- Turbolinks.loadPage null, xhr, turboOptions
29
- else
30
- Turbolinks.visit newUrl, turboOptions
31
-
32
- Page.open = ->
33
- window.open(arguments...)
34
-
35
- # Providing hooks for objects to set up destructors:
36
- onReplaceCallbacks = []
37
-
38
- # e.g., Page.onReplace(node, unbindListenersFnc)
39
- # unbindListenersFnc will be called if the node in question is partially replaced
40
- # or if a full replace occurs. It will be called only once
41
- Page.onReplace = (node, callback) ->
42
- throw new Error("Page.onReplace: Node and callback must both be specified") if !node || !callback
43
- throw new Error("Page.onReplace: Callback must be a function") if !isFunction(callback)
44
- onReplaceCallbacks.push({node, callback})
45
-
46
- # option C from http://jsperf.com/alternative-isfunction-implementations
47
- isFunction = (object) ->
48
- !!(object && object.constructor && object.call && object.apply)
49
-
50
- # roughly based on http://davidwalsh.name/check-parent-node (note, OP is incorrect)
51
- contains = (parentNode, childNode) ->
52
- if parentNode.contains
53
- parentNode.contains(childNode)
54
- else # old browser compatability
55
- !!((parentNode == childNode) || (parentNode.compareDocumentPosition(childNode) & Node.DOCUMENT_POSITION_CONTAINED_BY))
56
-
57
- document.addEventListener 'page:before-partial-replace', (event) ->
58
- replacedNodes = event.data
59
-
60
- unprocessedOnReplaceCallbacks = []
61
- for entry in onReplaceCallbacks
62
- fired = false
63
- for replacedNode in replacedNodes
64
- if contains(replacedNode, entry.node)
65
- entry.callback()
66
- fired = true
67
- break
68
-
69
- unless fired
70
- unprocessedOnReplaceCallbacks.push(entry)
71
-
72
- onReplaceCallbacks = unprocessedOnReplaceCallbacks
73
-
74
- document.addEventListener 'page:before-replace', (event) ->
75
- for entry in onReplaceCallbacks
76
- entry.callback()
77
- onReplaceCallbacks = []
@@ -1,179 +0,0 @@
1
- class TurboGraft.Remote
2
- constructor: (@opts, form, target) ->
3
-
4
- @initiator = form || target
5
-
6
- @actualRequestType = if @opts.httpRequestType?.toLowerCase() == 'get' then 'GET' else 'POST'
7
- @useNativeEncoding = @opts.useNativeEncoding
8
-
9
- @formData = @createPayload(form)
10
-
11
- @refreshOnSuccess = @opts.refreshOnSuccess.split(" ") if @opts.refreshOnSuccess
12
- @refreshOnSuccessExcept = @opts.refreshOnSuccessExcept.split(" ") if @opts.refreshOnSuccessExcept
13
- @refreshOnError = @opts.refreshOnError.split(" ") if @opts.refreshOnError
14
- @refreshOnErrorExcept = @opts.refreshOnErrorExcept.split(" ") if @opts.refreshOnErrorExcept
15
-
16
- xhr = new XMLHttpRequest
17
- if @actualRequestType == 'GET'
18
- url = if @formData then @opts.httpUrl + "?#{@formData}" else @opts.httpUrl
19
- xhr.open(@actualRequestType, url, true)
20
- else
21
- xhr.open(@actualRequestType, @opts.httpUrl, true)
22
- xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest')
23
- xhr.setRequestHeader('Accept', 'text/html, application/xhtml+xml, application/xml')
24
- xhr.setRequestHeader("Content-Type", @contentType) if @contentType
25
- xhr.setRequestHeader 'X-XHR-Referer', document.location.href
26
-
27
- csrfToken = CSRFToken.get().token
28
- xhr.setRequestHeader('X-CSRF-Token', csrfToken) if csrfToken
29
-
30
- triggerEventFor('turbograft:remote:init', @initiator, {xhr: xhr, initiator: @initiator})
31
-
32
- xhr.addEventListener 'loadstart', =>
33
- triggerEventFor 'turbograft:remote:start', @initiator,
34
- xhr: xhr
35
-
36
- xhr.addEventListener 'error', @onError
37
- xhr.addEventListener 'load', (event) =>
38
- if xhr.status < 400
39
- @onSuccess(event)
40
- else
41
- @onError(event)
42
-
43
- xhr.addEventListener 'loadend', =>
44
- @opts.done?()
45
- triggerEventFor 'turbograft:remote:always', @initiator,
46
- initiator: @initiator
47
- xhr: xhr
48
-
49
- @xhr = xhr
50
-
51
- submit: ->
52
- @xhr.send(@formData)
53
-
54
- createPayload: (form) ->
55
- if form
56
- if @useNativeEncoding || form.querySelectorAll("[type='file'][name]").length > 0
57
- formData = @nativeEncodeForm(form)
58
- else # for much smaller payloads
59
- formData = @uriEncodeForm(form)
60
- else
61
- formData = ''
62
-
63
- if formData not instanceof FormData
64
- @contentType = "application/x-www-form-urlencoded; charset=UTF-8"
65
- formData = @formAppend(formData, "_method", @opts.httpRequestType) if formData.indexOf("_method") == -1 && @opts.httpRequestType && @actualRequestType != 'GET'
66
-
67
- formData
68
-
69
- formAppend: (uriEncoded, key, value) ->
70
- uriEncoded += "&" if uriEncoded.length
71
- uriEncoded += "#{encodeURIComponent(key)}=#{encodeURIComponent(value)}"
72
-
73
- uriEncodeForm: (form) ->
74
- formData = ""
75
- @_iterateOverFormInputs form, (input) =>
76
- formData = @formAppend(formData, input.name, input.value)
77
- formData
78
-
79
- formDataAppend: (formData, input) ->
80
- if input.type == 'file'
81
- for file in input.files
82
- formData.append(input.name, file)
83
- else
84
- formData.append(input.name, input.value)
85
- formData
86
-
87
- nativeEncodeForm: (form) ->
88
- formData = new FormData
89
- @_iterateOverFormInputs form, (input) =>
90
- formData = @formDataAppend(formData, input)
91
- formData
92
-
93
- _iterateOverFormInputs: (form, callback) ->
94
- inputs = @_enabledInputs(form)
95
- for input in inputs
96
- inputEnabled = !input.disabled
97
- radioOrCheck = (input.type == 'checkbox' || input.type == 'radio')
98
-
99
- if inputEnabled && input.name
100
- if (radioOrCheck && input.checked) || !radioOrCheck
101
- callback(input)
102
-
103
- _enabledInputs: (form) ->
104
- selector = "input:not([type='reset']):not([type='button']):not([type='submit']):not([type='image']), select, textarea"
105
- inputs = Array::slice.call(form.querySelectorAll(selector))
106
- disabledNodes = Array::slice.call(TurboGraft.querySelectorAllTGAttribute(form, 'tg-remote-noserialize'))
107
-
108
- return inputs unless disabledNodes.length
109
-
110
- disabledInputs = disabledNodes
111
- for node in disabledNodes
112
- disabledInputs = disabledInputs.concat(Array::slice.call(node.querySelectorAll(selector)))
113
-
114
- enabledInputs = []
115
- for input in inputs when disabledInputs.indexOf(input) < 0
116
- enabledInputs.push(input)
117
- enabledInputs
118
-
119
- onSuccess: (ev) =>
120
- @opts.success?()
121
-
122
- xhr = ev.target
123
- triggerEventFor 'turbograft:remote:success', @initiator,
124
- initiator: @initiator
125
- xhr: xhr
126
-
127
- if redirect = xhr.getResponseHeader('X-Next-Redirect')
128
- Page.visit(redirect, reload: true)
129
- return
130
-
131
- unless TurboGraft.hasTGAttribute(@initiator, 'tg-remote-norefresh')
132
- if @opts.fullRefresh && @refreshOnSuccess
133
- Page.refresh(onlyKeys: @refreshOnSuccess)
134
- else if @opts.fullRefresh
135
- Page.refresh()
136
- else if @refreshOnSuccess
137
- Page.refresh(
138
- response: xhr
139
- onlyKeys: @refreshOnSuccess
140
- )
141
- else if @refreshOnSuccessExcept
142
- Page.refresh(
143
- response: xhr
144
- exceptKeys: @refreshOnSuccessExcept
145
- )
146
- else
147
- Page.refresh(
148
- response: xhr
149
- )
150
-
151
- onError: (ev) =>
152
- @opts.fail?()
153
-
154
- xhr = ev.target
155
- triggerEventFor 'turbograft:remote:fail', @initiator,
156
- initiator: @initiator
157
- xhr: xhr
158
-
159
- if TurboGraft.hasTGAttribute(@initiator, 'tg-remote-norefresh')
160
- triggerEventFor 'turbograft:remote:fail:unhandled', @initiator,
161
- xhr: xhr
162
- else
163
- if @opts.fullRefresh && @refreshOnError
164
- Page.refresh(onlyKeys: @refreshOnError)
165
- else if @opts.fullRefresh
166
- Page.refresh()
167
- else if @refreshOnError
168
- Page.refresh(
169
- response: xhr
170
- onlyKeys: @refreshOnError
171
- )
172
- else if @refreshOnErrorExcept
173
- Page.refresh(
174
- response: xhr
175
- exceptKeys: @refreshOnErrorExcept
176
- )
177
- else
178
- triggerEventFor 'turbograft:remote:fail:unhandled', @initiator,
179
- xhr: xhr
@@ -1,31 +0,0 @@
1
- class TurboGraft.Response
2
- constructor: (@xhr, intendedURL) ->
3
- if intendedURL && intendedURL.withoutHash() != @xhr.responseURL
4
- redirectedTo = @xhr.responseURL
5
- else
6
- redirectedTo = @xhr.getResponseHeader('X-XHR-Redirected-To')
7
-
8
- @finalURL = redirectedTo || intendedURL
9
-
10
- valid: -> @hasRenderableHttpStatus() && @hasValidContent()
11
-
12
- document: ->
13
- if @valid()
14
- TurboGraft.Document.create(@xhr.responseText)
15
-
16
- hasRenderableHttpStatus: ->
17
- return true if @xhr.status == 422 # we want to render form validations
18
- !(400 <= @xhr.status < 600)
19
-
20
- hasValidContent: ->
21
- if contentType = @xhr.getResponseHeader('Content-Type')
22
- contentType.match(/^(?:text\/html|application\/xhtml\+xml|application\/xml)(?:;|$)/)
23
- else
24
- throw new Error("Error encountered for XHR Response: #{this}")
25
-
26
- toString: () ->
27
- "URL: #{@xhr.responseURL}, " +
28
- "ReadyState: #{@xhr.readyState}, " +
29
- "Headers: #{@xhr.getAllResponseHeaders()}"
30
-
31
- TurboGraft.location = () -> location.href