turbograft 0.4.8 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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