wiselinks-artirix 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.gitignore +51 -0
  4. data/.rspec +2 -0
  5. data/.travis.yml +4 -0
  6. data/Gemfile +7 -0
  7. data/Gemfile.lock +184 -0
  8. data/LICENSE +20 -0
  9. data/README.md +479 -0
  10. data/Rakefile +10 -0
  11. data/app/views/layouts/wiselinks.html.erb +1 -0
  12. data/compiler.jar +0 -0
  13. data/lib/assets/javascripts/_dom_parser.js.coffee +50 -0
  14. data/lib/assets/javascripts/_form.js.coffee +74 -0
  15. data/lib/assets/javascripts/_link.js.coffee +44 -0
  16. data/lib/assets/javascripts/_page.js.coffee +108 -0
  17. data/lib/assets/javascripts/_request_manager.js.coffee +132 -0
  18. data/lib/assets/javascripts/_response.js.coffee +101 -0
  19. data/lib/assets/javascripts/lib/native.history.js +3337 -0
  20. data/lib/assets/javascripts/wiselinks.js.coffee +37 -0
  21. data/lib/wiselinks-artirix.rb +1 -0
  22. data/lib/wiselinks.rb +27 -0
  23. data/lib/wiselinks/controller_methods.rb +67 -0
  24. data/lib/wiselinks/helpers.rb +9 -0
  25. data/lib/wiselinks/logger.rb +11 -0
  26. data/lib/wiselinks/rails.rb +22 -0
  27. data/lib/wiselinks/rendering.rb +37 -0
  28. data/lib/wiselinks/request.rb +29 -0
  29. data/lib/wiselinks/version.rb +12 -0
  30. data/spec/cases/helpers_spec.rb +8 -0
  31. data/spec/cases/request_spec.rb +113 -0
  32. data/spec/dummy/README.rdoc +261 -0
  33. data/spec/dummy/Rakefile +7 -0
  34. data/spec/dummy/app/assets/javascripts/application.js.coffee +1 -0
  35. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  36. data/spec/dummy/app/controllers/application_controller.rb +9 -0
  37. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  38. data/spec/dummy/app/mailers/.gitkeep +0 -0
  39. data/spec/dummy/app/models/.gitkeep +0 -0
  40. data/spec/dummy/app/views/application/index.html.erb +1 -0
  41. data/spec/dummy/app/views/application/no_slash.html.erb +0 -0
  42. data/spec/dummy/app/views/application/trailing_slash.html.erb +0 -0
  43. data/spec/dummy/app/views/layouts/application.html.erb +15 -0
  44. data/spec/dummy/config.ru +4 -0
  45. data/spec/dummy/config/application.rb +59 -0
  46. data/spec/dummy/config/boot.rb +10 -0
  47. data/spec/dummy/config/database.yml +7 -0
  48. data/spec/dummy/config/environment.rb +5 -0
  49. data/spec/dummy/config/environments/development.rb +37 -0
  50. data/spec/dummy/config/environments/production.rb +67 -0
  51. data/spec/dummy/config/environments/test.rb +40 -0
  52. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  53. data/spec/dummy/config/initializers/inflections.rb +15 -0
  54. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  55. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  56. data/spec/dummy/config/initializers/session_store.rb +8 -0
  57. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  58. data/spec/dummy/config/locales/en.yml +5 -0
  59. data/spec/dummy/config/routes.rb +7 -0
  60. data/spec/dummy/lib/assets/.gitkeep +0 -0
  61. data/spec/dummy/log/.gitkeep +0 -0
  62. data/spec/dummy/log/development.log +27917 -0
  63. data/spec/dummy/public/404.html +26 -0
  64. data/spec/dummy/public/422.html +26 -0
  65. data/spec/dummy/public/500.html +25 -0
  66. data/spec/dummy/public/assets/application-a98e47eb93026a340a766faf55214702.js +2830 -0
  67. data/spec/dummy/public/assets/application-a98e47eb93026a340a766faf55214702.js.gz +0 -0
  68. data/spec/dummy/public/assets/application-ecf5beebe0b79251c8be40f0443074f2.css +14 -0
  69. data/spec/dummy/public/assets/application-ecf5beebe0b79251c8be40f0443074f2.css.gz +0 -0
  70. data/spec/dummy/public/assets/application.css +14 -0
  71. data/spec/dummy/public/assets/application.css.gz +0 -0
  72. data/spec/dummy/public/assets/application.js +2830 -0
  73. data/spec/dummy/public/assets/application.js.gz +0 -0
  74. data/spec/dummy/public/assets/manifest.yml +5 -0
  75. data/spec/dummy/public/favicon.ico +0 -0
  76. data/spec/dummy/public/javascripts/wisepdf.js +1 -0
  77. data/spec/dummy/public/stylesheets/wisepdf.css +1 -0
  78. data/spec/dummy/script/rails +6 -0
  79. data/spec/dummy/tmp/cache/assets/C26/0A0/sprockets%2F52456508a38f02f4559064b24980c87a +0 -0
  80. data/spec/dummy/tmp/cache/assets/C5E/890/sprockets%2Ffb6525457b6873e6905e2d522548091f +0 -0
  81. data/spec/dummy/tmp/cache/assets/C80/150/sprockets%2F0d3881005b0646df783d5c24683d34f5 +0 -0
  82. data/spec/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
  83. data/spec/dummy/tmp/cache/assets/CF3/250/sprockets%2F7edb1809ce839a3d290508f935c89f42 +0 -0
  84. data/spec/dummy/tmp/cache/assets/D09/C40/sprockets%2Fcf317b95ed0500b7277e950a9c0c82e0 +0 -0
  85. data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  86. data/spec/dummy/tmp/cache/assets/D45/760/sprockets%2Fbc659a6e09b5025e8be539b0b68f71f2 +0 -0
  87. data/spec/dummy/tmp/cache/assets/D4E/D00/sprockets%2F1a6846f0a837ae2524e2f9ec89e6ef43 +0 -0
  88. data/spec/dummy/tmp/cache/assets/D55/090/sprockets%2F4a21bc343a4696b7603ea4cc25c3c3ba +0 -0
  89. data/spec/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
  90. data/spec/dummy/tmp/cache/assets/DC2/EB0/sprockets%2F75b4716f479a2acfac51b258fba0c2bd +0 -0
  91. data/spec/dummy/tmp/cache/assets/DF1/B80/sprockets%2Fcd0ee4f742908cb7223a1e7be4a4ccbc +0 -0
  92. data/spec/dummy/tmp/cache/assets/E11/4E0/sprockets%2F86e145a39f85cceeaffdff91ebb61449 +0 -0
  93. data/spec/factories/requests.rb +30 -0
  94. data/spec/helper.rb +26 -0
  95. data/spec/requests/trailing_slash_spec.rb +17 -0
  96. data/wiselinks-artirix.gemspec +40 -0
  97. metadata +432 -0
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ require 'wiselinks/builder'
7
+
8
+ RSpec::Core::RakeTask.new('spec')
9
+
10
+ task :default => :spec
@@ -0,0 +1 @@
1
+ <%= yield %>
data/compiler.jar ADDED
Binary file
@@ -0,0 +1,50 @@
1
+ class DOMParser
2
+ parse: (html) ->
3
+ @_get_parser()(html)
4
+
5
+ _get_parser: ->
6
+ @_document_parser ?= @_parser_factory()
7
+
8
+ # fully taken from Turbolinks (https://github.com/rails/turbolinks)
9
+ # and changed function names style
10
+ # by @igor-alexandrov request :)
11
+ _parser_factory: ->
12
+ create_document_using_parser = (html) ->
13
+ (new DOMParser).parseFromString html, 'text/html'
14
+
15
+ create_document_using_DOM = (html) ->
16
+ doc = document.implementation.createHTMLDocument ''
17
+ doc.documentElement.innerHTML = html
18
+ doc
19
+
20
+ create_document_using_write = (html) ->
21
+ doc = document.implementation.createHTMLDocument ''
22
+ doc.open 'replace'
23
+ doc.write html
24
+ doc.close()
25
+ doc
26
+
27
+ # Use create_document_using_parser if DOMParser is defined and natively
28
+ # supports 'text/html' parsing (Firefox 12+, IE 10)
29
+ #
30
+ # Use create_document_using_DOM if create_document_using_parser throws an exception
31
+ # due to unsupported type 'text/html' (Firefox < 12, Opera)
32
+ #
33
+ # Use create_document_using_write if:
34
+ # - DOMParser isn't defined
35
+ # - create_document_using_parser returns null due to unsupported type 'text/html' (Chrome, Safari)
36
+ # - create_document_using_DOM doesn't create a valid HTML document (safeguarding against potential edge cases)
37
+ try
38
+ if window.DOMParser
39
+ testDoc = create_document_using_parser '<html><body><p>test'
40
+ create_document_using_parser
41
+ catch e
42
+ testDoc = create_document_using_DOM '<html><body><p>test'
43
+ create_document_using_DOM
44
+ finally
45
+ unless testDoc?.body?.childNodes.length is 1
46
+ return create_document_using_write
47
+
48
+
49
+ window._Wiselinks ?= {}
50
+ window._Wiselinks.DOMParser = DOMParser
@@ -0,0 +1,74 @@
1
+ class Form
2
+ constructor: (@page, @$form) ->
3
+
4
+ process: ->
5
+ self = this
6
+
7
+ if self._include_blank_url_params()
8
+ self.page.load(self._url(), self._target(), self._type())
9
+ else
10
+ self._without_blank_url_params(
11
+ ->
12
+ self.page.load(self._url(), self._target(), self._type())
13
+ )
14
+
15
+ _without_blank_url_params: (callback) ->
16
+ selector = 'select:not(:disabled),input:not(:disabled)'
17
+ $disable = @$form.find(selector).filter(-> !$(this).val())
18
+
19
+ $disable.attr('disabled', true)
20
+ callback()
21
+ $disable.attr('disabled', false)
22
+
23
+ _params: ->
24
+ hash = {}
25
+
26
+ for item in @$form.serializeArray()
27
+ if item.name != 'utf8'
28
+ # if name ends with [], then we try to optimize it
29
+ name = if item.name.indexOf('[]', item.name.length - '[]'.length) != -1
30
+ item.name.substr(0, item.name.length - 2)
31
+ else
32
+ item.name
33
+
34
+ if hash[name]?
35
+ hash[name] = hash[name] + ",#{item.value}"
36
+ else
37
+ hash[name] = item.value
38
+
39
+ hash
40
+
41
+ _include_blank_url_params: ->
42
+ @$form.data('include-blank-url-params') == true
43
+
44
+ _optimize_url_params: ->
45
+ @$form.data('optimize-url-params') != false
46
+
47
+ _type: ->
48
+ if (@$form.data('push') == 'partial') then 'partial' else 'template'
49
+
50
+ _target: ->
51
+ @$form.data('target')
52
+
53
+ _url: ->
54
+ self = this
55
+
56
+ serialized = if self._optimize_url_params()
57
+ params = []
58
+
59
+ # To find out why encodeURIComponent should be used, follow the link:
60
+ # http://stackoverflow.com/questions/75980/best-practice-escape-or-encodeuri-encodeuricomponent
61
+ #
62
+ for key, value of this._params()
63
+ params.push("#{key}=#{encodeURIComponent(value).replace(/%2C/g, ',')}")
64
+
65
+ params.join('&')
66
+ else
67
+ @$form.serialize()
68
+
69
+ url = @$form.attr("action").replace(/\?.*$/, '')
70
+ url += "?#{serialized}" if serialized.length > 0
71
+ url
72
+
73
+ window._Wiselinks ?= {}
74
+ window._Wiselinks.Form = Form
@@ -0,0 +1,44 @@
1
+ class Link
2
+ constructor: (@page, @$link) ->
3
+
4
+ allows_process: (event) ->
5
+ !(this._cross_origin_link(event.currentTarget) ||
6
+ this._non_standard_click(event))
7
+
8
+ process: ->
9
+ type = if (@$link.data('push') == 'partial')
10
+ 'partial'
11
+ else
12
+ 'template'
13
+
14
+ @page.load(@$link.attr("href"), @$link.data('target'), type)
15
+
16
+ _cross_origin_link: (link) ->
17
+ this._different_protocol(link) ||
18
+ this._different_host(link) ||
19
+ this._different_port(link)
20
+
21
+ _different_protocol: (link) ->
22
+ return false if link.protocol == ':' || link.protocol == ''
23
+ location.protocol != link.protocol
24
+
25
+ # IE returns host with port and all other browsers return host without port
26
+ #
27
+ _different_host: (link) ->
28
+ return false if link.host == ''
29
+ (location.host.split(':')[0] != link.host.split(':')[0])
30
+
31
+ # IE returns for link.port "80" but the location.port is ""
32
+ # Stupid but "modern" browsers return correct values
33
+ #
34
+ _different_port: (link) ->
35
+ port_equals = (location.port == link.port) ||
36
+ (location.port == '' && (link.port == "80" || link.port == "443"))
37
+
38
+ !port_equals
39
+
40
+ _non_standard_click: (event) ->
41
+ event.metaKey || event.ctrlKey || event.shiftKey || event.altKey
42
+
43
+ window._Wiselinks = {} if window._Wiselinks == undefined
44
+ window._Wiselinks.Link = Link
@@ -0,0 +1,108 @@
1
+ #= require _request_manager
2
+
3
+ class Page
4
+ constructor: (@$target, @options) ->
5
+ self = this
6
+
7
+ @template_id = new Date().getTime()
8
+ @request_manager = new _Wiselinks.RequestManager(@options)
9
+
10
+ @$target = self._wrap(@$target)
11
+
12
+ self._try_target(@$target)
13
+
14
+ if History.emulated.pushState && @options.html4 == true
15
+ if window.location.href.indexOf('#.') == -1 &&
16
+ @options.html4_normalize_path == true &&
17
+ window.location.pathname != @options.html4_root_path
18
+
19
+ window.location.href = "#{window.location.protocol}//#{window.location.host}#{@options.html4_root_path}#.#{window.location.pathname}"
20
+
21
+ History.Adapter.bind(
22
+ window,
23
+ "statechange"
24
+ (event, data) ->
25
+ state = History.getState()
26
+
27
+ if self._template_id_changed(state)
28
+ self._call(self._reset_state(state))
29
+ else
30
+ self._call(state)
31
+ )
32
+
33
+ $(document).on(
34
+ 'click', 'a[data-push], a[data-replace]'
35
+ (event) ->
36
+ if (link = new _Wiselinks.Link(self, $(this))).allows_process(event)
37
+ event.preventDefault()
38
+ link.process()
39
+
40
+ return false
41
+ )
42
+
43
+ $(document).on(
44
+ 'submit', 'form[data-push], form[data-replace]'
45
+ (event) ->
46
+ if (form = new _Wiselinks.Form(self, $(this)))
47
+ event.preventDefault()
48
+ form.process()
49
+
50
+ return false
51
+ )
52
+
53
+ load: (url, target, render = 'template') ->
54
+ @template_id = new Date().getTime() if render != 'partial'
55
+
56
+ selector = if target?
57
+ $target = this._wrap(target)
58
+ this._try_target($target)
59
+ $target.selector
60
+
61
+ History.pushState({
62
+ timestamp: (new Date().getTime()),
63
+ template_id: @template_id,
64
+ render: render,
65
+ target: selector,
66
+ referer: window.location.href
67
+ }, document.title, url )
68
+
69
+ reload: () ->
70
+ History.replaceState({
71
+ timestamp: (new Date().getTime()),
72
+ template_id: @template_id,
73
+ render: 'template',
74
+ referer: window.location.href
75
+ }, document.title, History.getState().url )
76
+
77
+ _call: (state) ->
78
+ $target = if state.data.target? then $(state.data.target) else @$target
79
+ this.request_manager.call($target, state)
80
+
81
+ _template_id_changed: (state) ->
82
+ !state.data.template_id? || state.data.template_id != @template_id
83
+
84
+ _make_state: (url, target, render = 'template', referer) ->
85
+ {
86
+ url: url
87
+ data:
88
+ target: target
89
+ render: render
90
+ referer: referer
91
+ }
92
+
93
+ _reset_state: (state) ->
94
+ state.data = {} unless state.data?
95
+ state.data.target = null
96
+ state.data.render = 'template'
97
+ state
98
+
99
+ _try_target: ($target) ->
100
+ if $target.length == 0 && @options.target_missing == 'exception'
101
+ throw new Error("[Wiselinks] Target missing: `#{$target.selector}`")
102
+
103
+ _wrap: (object) ->
104
+ $(object)
105
+
106
+
107
+ window._Wiselinks = {} if window._Wiselinks == undefined
108
+ window._Wiselinks.Page = Page
@@ -0,0 +1,132 @@
1
+ #= require _response
2
+
3
+ class RequestManager
4
+ constructor: (@options = {}) ->
5
+
6
+ call: ($target, state) ->
7
+ self = this
8
+
9
+ # If been redirected, just trigger event and exit
10
+ #
11
+ if @redirected?
12
+ @redirected = null
13
+ return
14
+
15
+ # Trigger loading event
16
+ #
17
+ self._loading($target, state)
18
+
19
+ # Perform XHtmlHttpRequest
20
+ #
21
+ $.ajax(
22
+ url: state.url
23
+ headers:
24
+ 'X-Wiselinks': state.data.render
25
+ 'X-Wiselinks-Referer': state.data.referer
26
+
27
+ dataType: "html"
28
+ ).done(
29
+ (data, status, xhr) ->
30
+ self._html_loaded($target, data, status, xhr)
31
+ ).fail(
32
+ (xhr, status, error) ->
33
+ self._fail($target, status, state, error, xhr.status, xhr.responseText)
34
+ ).always(
35
+ (data_or_xhr, status, xhr_or_error)->
36
+ self._always($target, status, state)
37
+ )
38
+
39
+ _normalize: (url) ->
40
+ return unless url?
41
+
42
+ url = url.replace /\/+$/, ''
43
+ url
44
+
45
+ _assets_changed: (assets_digest) ->
46
+ @options.assets_digest? && @options.assets_digest != assets_digest
47
+
48
+ _redirect_to: (url, $target, state, xhr) ->
49
+ if ( xhr && xhr.readyState < 4)
50
+ xhr.onreadystatechange = $.noop
51
+ xhr.abort()
52
+
53
+ @redirected = true
54
+ $(document).trigger('page:redirected', [$target, state.data.render, url])
55
+ History.replaceState(state.data, document.title, url)
56
+
57
+ _loading: ($target, state) ->
58
+ $(document).trigger('page:loading'
59
+ [$target, state.data.render, decodeURI(state.url)]
60
+ )
61
+
62
+ _done: ($target, status, state, data) ->
63
+ $(document).trigger('page:done'
64
+ [$target, status, decodeURI(state.url), data]
65
+ )
66
+
67
+ _html_loaded: ($target, data, status, xhr) ->
68
+ forcePartial = @options.forcePartial || false
69
+ response = new window._Wiselinks.Response(data, xhr, $target, forcePartial)
70
+
71
+ url = @_normalize(response.url())
72
+ assets_digest = response.assets_digest()
73
+
74
+ if @_assets_changed(assets_digest)
75
+ window.location.reload(true)
76
+ else
77
+ state = History.getState()
78
+ if url? && (url != @_normalize(state.url))
79
+ @_redirect_to(url, $target, state, xhr)
80
+
81
+ $target.html(response.content()).promise().done(
82
+ =>
83
+ @_title(response.title())
84
+ @_description(response.description())
85
+ @_canonical(response.canonical())
86
+ @_robots(response.robots())
87
+ @_link_rel_prev(response.link_rel_prev())
88
+ @_link_rel_next(response.link_rel_next())
89
+ @_done($target, status, state, response.content())
90
+ )
91
+
92
+ _fail: ($target, status, state, error, code, data) ->
93
+ $(document).trigger('page:fail'
94
+ [$target, status, decodeURI(state.url), error, code, data]
95
+ )
96
+
97
+ _always: ($target, status, state) ->
98
+ $(document).trigger('page:always', [$target, status, decodeURI(state.url)])
99
+
100
+ _title: (value) ->
101
+ if value?
102
+ $(document).trigger('page:title', decodeURI(value))
103
+ document.title = decodeURI(value)
104
+
105
+ _description: (value) ->
106
+ if value?
107
+ $(document).trigger('page:description', decodeURI(value))
108
+ $('meta[name="description"]').attr('content', decodeURI(value))
109
+
110
+ _canonical: (value) ->
111
+ if value?
112
+ $(document).trigger('page:canonical', decodeURI(value))
113
+ $('link[rel="canonical"]').attr('href', decodeURI(value))
114
+
115
+ _robots: (value) ->
116
+ if value?
117
+ $(document).trigger('page:robots', decodeURI(value))
118
+ $('meta[name="robots"]').attr('content', decodeURI(value))
119
+
120
+ _link_rel_prev: (value) ->
121
+ if value?
122
+ $(document).trigger('page:link_rel_prev', decodeURI(value))
123
+ $('link[rel="prev"]').attr('href', decodeURI(value))
124
+
125
+ _link_rel_next: (value) ->
126
+ if value?
127
+ $(document).trigger('page:link_rel_next', decodeURI(value))
128
+ $('link[rel="next"]').attr('href', decodeURI(value))
129
+
130
+
131
+ window._Wiselinks = {} if window._Wiselinks == undefined
132
+ window._Wiselinks.RequestManager = RequestManager
@@ -0,0 +1,101 @@
1
+ #= require _dom_parser
2
+
3
+ # if server responds with 304, sometimes you may get
4
+ # full page source instead of just wiselinks part, so
5
+ # you need to use different content extract strategies
6
+ class Response
7
+ @_document_parser: null
8
+
9
+ @_get_document_parser: ->
10
+ Response._document_parser ?= new window._Wiselinks.DOMParser
11
+
12
+
13
+ constructor: (@html, @xhr, @$target, @forcePartial = false) ->
14
+
15
+ url: ->
16
+ @xhr.getResponseHeader('X-Wiselinks-Url')
17
+
18
+ assets_digest: ->
19
+ if @_is_full_document_response()
20
+ $('meta[name="assets-digest"]', @_get_doc()).attr('content')
21
+ else
22
+ @xhr.getResponseHeader('X-Wiselinks-Assets-Digest')
23
+
24
+ content: ->
25
+ @_content ?= @_extract_content()
26
+
27
+ title: ->
28
+ @_title ?= @_extract_title()
29
+
30
+ _extract_title: ->
31
+ if @_is_full_document_response()
32
+ $('title', @_get_doc()).text()
33
+ else
34
+ @xhr.getResponseHeader('X-Wiselinks-Title')
35
+
36
+ description: ->
37
+ @_description ?= @_extract_description()
38
+
39
+ _extract_description: ->
40
+ if @_is_full_document_response()
41
+ $('meta[name="description"]', @_get_doc()).text()
42
+ else
43
+ @xhr.getResponseHeader('X-Wiselinks-Description')
44
+
45
+ canonical: ->
46
+ @_canonical ?= @_extract_canonical()
47
+
48
+ _extract_canonical: ->
49
+ if @_is_full_document_response()
50
+ $('link[rel="canonical"]', @_get_doc()).text()
51
+ else
52
+ @xhr.getResponseHeader('X-Wiselinks-Canonical')
53
+
54
+
55
+ robots: ->
56
+ @_robots ?= @_extract_robots()
57
+
58
+ _extract_robots: ->
59
+ if @_is_full_document_response()
60
+ $('meta[name="robots"]', @_get_doc()).text()
61
+ else
62
+ @xhr.getResponseHeader('X-Wiselinks-Robots')
63
+
64
+
65
+ link_rel_prev: ->
66
+ @_link_rel_prev ?= @_extract_link_rel_prev()
67
+
68
+ _extract_link_rel_prev: ->
69
+ if @_is_full_document_response()
70
+ $('link[rel="prev"]', @_get_doc()).text()
71
+ else
72
+ @xhr.getResponseHeader('X-Wiselinks-LinkRelPrev')
73
+
74
+ link_rel_next: ->
75
+ @_link_rel_next ?= @_extract_link_rel_next()
76
+
77
+ _extract_link_rel_next: ->
78
+ if @_is_full_document_response()
79
+ $('link[rel="next"]', @_get_doc()).text()
80
+ else
81
+ @xhr.getResponseHeader('X-Wiselinks-LinkRelNext')
82
+
83
+ _extract_content: ->
84
+ if @_is_full_document_response()
85
+ @_get_doc_target_node().html()
86
+ else
87
+ @html
88
+
89
+ _is_full_document_response: ->
90
+ @_get_doc_target_node().length is 1 && !@forcePartial
91
+
92
+ _get_doc_target_node: ->
93
+ @$doc_target_node ?= $(@$target.selector, @_get_doc())
94
+
95
+ _get_doc: ->
96
+ @_doc ?= Response._get_document_parser().parse(@html)
97
+
98
+
99
+
100
+ window._Wiselinks ?= {}
101
+ window._Wiselinks.Response = Response