turbograft 0.1.15 → 0.1.16

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f0cae3c571903c38a3f4202abcf69b3be1759c79
4
- data.tar.gz: 1763b567311c50e6a20348c2b68a8fdc2b872084
3
+ metadata.gz: 3a484dc5c71d248936bbac0a9dbf199f45677dd2
4
+ data.tar.gz: 34a5ec53588bf5f1a22414d71f5c2a00d13bf27b
5
5
  SHA512:
6
- metadata.gz: 39adb2b25cb0414a2360850d35a82c418a96f884d6648b6f682f630127e13b2dcf79f9edaeea641ce46a58076107007a961c49329be397e09af83e81decc2d30
7
- data.tar.gz: 115abe752d2a6e1c7300007dad6acb16c1cdc0878d78a16ad05bbfb4b620a13a8f422dc0307324d32f5eccfcafce96aa44c207520b574f472649cad61e975c24
6
+ metadata.gz: 2210ec33b3ee750852288282c80171af7ee1558551496c6b72695e6276ff23d7a5da64e78b19f97cb44cbdc49e9ea90eb23f22b2f156d6dee4454618097f8299
7
+ data.tar.gz: 36db02f2045e1ae7d8f4fe24b97f244e822983c95f3bdf27ea3768a286de7338405846854763d5271cae610de7478f9529a5adb0a2dadffe46148695b1e8e028
@@ -25,3 +25,47 @@ Page.refresh = (options = {}, callback) ->
25
25
 
26
26
  Page.open = ->
27
27
  window.open(arguments...)
28
+
29
+ # Providing hooks for objects to set up destructors:
30
+ onReplaceCallbacks = []
31
+
32
+ # e.g., Page.onReplace(node, unbindListenersFnc)
33
+ # unbindListenersFnc will be called if the node in question is partially replaced
34
+ # or if a full replace occurs. It will be called only once
35
+ Page.onReplace = (node, callback) ->
36
+ throw new Error("Page.onReplace: Node and callback must both be specified") if !node || !callback
37
+ throw new Error("Page.onReplace: Callback must be a function") if !isFunction(callback)
38
+ onReplaceCallbacks.push({node, callback})
39
+
40
+ # option C from http://jsperf.com/alternative-isfunction-implementations
41
+ isFunction = (object) ->
42
+ !!(object && object.constructor && object.call && object.apply)
43
+
44
+ # roughly based on http://davidwalsh.name/check-parent-node (note, OP is incorrect)
45
+ contains = (parentNode, childNode) ->
46
+ if parentNode.contains
47
+ parentNode.contains(childNode)
48
+ else # old browser compatability
49
+ !!((parentNode == childNode) || (parentNode.compareDocumentPosition(childNode) & Node.DOCUMENT_POSITION_CONTAINED_BY))
50
+
51
+ document.addEventListener 'page:before-partial-replace', (event) ->
52
+ replacedNodes = event.data
53
+
54
+ unprocessedOnReplaceCallbacks = []
55
+ for entry in onReplaceCallbacks
56
+ fired = false
57
+ for replacedNode in replacedNodes
58
+ if contains(replacedNode, entry.node)
59
+ entry.callback()
60
+ fired = true
61
+ break
62
+
63
+ unless fired
64
+ unprocessedOnReplaceCallbacks.push(entry)
65
+
66
+ onReplaceCallbacks = unprocessedOnReplaceCallbacks
67
+
68
+ document.addEventListener 'page:before-replace', (event) ->
69
+ for entry in onReplaceCallbacks
70
+ entry.callback()
71
+ onReplaceCallbacks = []
@@ -1,3 +1,3 @@
1
1
  module TurboGraft
2
- VERSION = '0.1.15'
2
+ VERSION = '0.1.16'
3
3
  end
data/lib/turbograft.js ADDED
@@ -0,0 +1,978 @@
1
+ (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2
+ window.Click = (function() {
3
+ Click.installHandlerLast = function(event) {
4
+ if (!event.defaultPrevented) {
5
+ document.removeEventListener('click', Click.handle, false);
6
+ return document.addEventListener('click', Click.handle, false);
7
+ }
8
+ };
9
+
10
+ Click.handle = function(event) {
11
+ return new Click(event);
12
+ };
13
+
14
+ function Click(event) {
15
+ this.event = event;
16
+ if (this.event.defaultPrevented) {
17
+ return;
18
+ }
19
+ this._extractLink();
20
+ if (this._validForTurbolinks()) {
21
+ if (!this._pageChangePrevented()) {
22
+ Turbolinks.visit(this.link.href);
23
+ }
24
+ this.event.preventDefault();
25
+ }
26
+ }
27
+
28
+ Click.prototype._pageChangePrevented = function() {
29
+ return !triggerEvent('page:before-change');
30
+ };
31
+
32
+ Click.prototype._extractLink = function() {
33
+ var link;
34
+ link = this.event.target;
35
+ while (!(!link.parentNode || link.nodeName === 'A')) {
36
+ link = link.parentNode;
37
+ }
38
+ if (link.nodeName === 'A' && link.href.length !== 0) {
39
+ return this.link = new Link(link);
40
+ }
41
+ };
42
+
43
+ Click.prototype._validForTurbolinks = function() {
44
+ return (this.link != null) && !(this.link.shouldIgnore() || this._nonStandardClick());
45
+ };
46
+
47
+ Click.prototype._nonStandardClick = function() {
48
+ return this.event.which > 1 || this.event.metaKey || this.event.ctrlKey || this.event.shiftKey || this.event.altKey;
49
+ };
50
+
51
+ return Click;
52
+
53
+ })();
54
+
55
+
56
+
57
+ },{}],2:[function(require,module,exports){
58
+ window.ComponentUrl = (function() {
59
+ function ComponentUrl(original) {
60
+ this.original = original != null ? original : document.location.href;
61
+ if (this.original.constructor === ComponentUrl) {
62
+ return this.original;
63
+ }
64
+ this._parse();
65
+ }
66
+
67
+ ComponentUrl.prototype.withoutHash = function() {
68
+ return this.href.replace(this.hash, '');
69
+ };
70
+
71
+ ComponentUrl.prototype.withoutHashForIE10compatibility = function() {
72
+ return this.withoutHash();
73
+ };
74
+
75
+ ComponentUrl.prototype.hasNoHash = function() {
76
+ return this.hash.length === 0;
77
+ };
78
+
79
+ ComponentUrl.prototype._parse = function() {
80
+ var _ref;
81
+ (this.link != null ? this.link : this.link = document.createElement('a')).href = this.original;
82
+ _ref = this.link, this.href = _ref.href, this.protocol = _ref.protocol, this.host = _ref.host, this.hostname = _ref.hostname, this.port = _ref.port, this.pathname = _ref.pathname, this.search = _ref.search, this.hash = _ref.hash;
83
+ this.origin = [this.protocol, '//', this.hostname].join('');
84
+ if (this.port.length !== 0) {
85
+ this.origin += ":" + this.port;
86
+ }
87
+ this.relative = [this.pathname, this.search, this.hash].join('');
88
+ return this.absolute = this.href;
89
+ };
90
+
91
+ return ComponentUrl;
92
+
93
+ })();
94
+
95
+
96
+
97
+ },{}],3:[function(require,module,exports){
98
+ window.CSRFToken = (function() {
99
+ function CSRFToken() {}
100
+
101
+ CSRFToken.get = function(doc) {
102
+ var tag;
103
+ if (doc == null) {
104
+ doc = document;
105
+ }
106
+ return {
107
+ node: tag = doc.querySelector('meta[name="csrf-token"]'),
108
+ token: tag != null ? typeof tag.getAttribute === "function" ? tag.getAttribute('content') : void 0 : void 0
109
+ };
110
+ };
111
+
112
+ CSRFToken.update = function(latest) {
113
+ var current;
114
+ current = this.get();
115
+ if ((current.token != null) && (latest != null) && current.token !== latest) {
116
+ return current.node.setAttribute('content', latest);
117
+ }
118
+ };
119
+
120
+ return CSRFToken;
121
+
122
+ })();
123
+
124
+
125
+
126
+ },{}],4:[function(require,module,exports){
127
+ var documentListenerForButtons, hasClass, nodeIsDisabled;
128
+
129
+ window.TurboGraft = {
130
+ handlers: {}
131
+ };
132
+
133
+ hasClass = function(node, search) {
134
+ var className, _i, _len, _ref;
135
+ _ref = node.classList;
136
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
137
+ className = _ref[_i];
138
+ if (className === search) {
139
+ return true;
140
+ }
141
+ }
142
+ return false;
143
+ };
144
+
145
+ nodeIsDisabled = function(node) {
146
+ return node.getAttribute('disabled') || hasClass(node, 'disabled');
147
+ };
148
+
149
+ TurboGraft.handlers.partialGraftClickHandler = function(ev) {
150
+ var href, keys, partialGraft, refresh, target;
151
+ target = ev.target;
152
+ partialGraft = target.getAttribute("partial-graft");
153
+ if (partialGraft == null) {
154
+ return;
155
+ }
156
+ ev.preventDefault();
157
+ href = target.getAttribute("href");
158
+ refresh = target.getAttribute("refresh");
159
+ if (href == null) {
160
+ throw "TurboGraft developer error: href is not defined on node " + target;
161
+ }
162
+ if (refresh == null) {
163
+ throw "TurboGraft developer error: refresh is not defined on node " + target;
164
+ }
165
+ keys = refresh.trim().split(" ");
166
+ return Page.refresh({
167
+ url: href,
168
+ onlyKeys: keys
169
+ });
170
+ };
171
+
172
+ TurboGraft.handlers.remoteMethodHandler = function(ev) {
173
+ var httpRequestType, httpUrl, onlyOnce, options, remote, target;
174
+ target = ev.target;
175
+ if (!target.getAttribute('remote-method')) {
176
+ return;
177
+ }
178
+ ev.preventDefault();
179
+ httpUrl = target.getAttribute('href');
180
+ httpRequestType = target.getAttribute('remote-method');
181
+ if (!httpRequestType) {
182
+ throw "Turbograft developer error: You did not provide a request type for remote-method";
183
+ }
184
+ if (!httpUrl) {
185
+ throw "Turbograft developer error: You did not provide a URL for remote-method";
186
+ }
187
+ if (onlyOnce = target.getAttribute("remote-once")) {
188
+ target.removeAttribute("remote-once");
189
+ target.removeAttribute("remote-method");
190
+ }
191
+ options = {
192
+ httpRequestType: httpRequestType,
193
+ httpUrl: httpUrl,
194
+ fullRefresh: target.getAttribute('full-refresh') != null,
195
+ refreshOnSuccess: target.getAttribute('refresh-on-success'),
196
+ refreshOnError: target.getAttribute('refresh-on-error')
197
+ };
198
+ remote = new TurboGraft.Remote(options);
199
+ };
200
+
201
+ documentListenerForButtons = function(eventType, handler, useCapture) {
202
+ if (useCapture == null) {
203
+ useCapture = false;
204
+ }
205
+ return document.addEventListener(eventType, function(ev) {
206
+ var target;
207
+ target = ev.target;
208
+ if (!(target.nodeName === "A" || target.nodeName === "BUTTON") || nodeIsDisabled(target)) {
209
+ return;
210
+ }
211
+ return handler(ev);
212
+ });
213
+ };
214
+
215
+ documentListenerForButtons('click', TurboGraft.handlers.partialGraftClickHandler, true);
216
+
217
+ documentListenerForButtons('click', TurboGraft.handlers.remoteMethodHandler, true);
218
+
219
+
220
+
221
+ },{}],5:[function(require,module,exports){
222
+ var __hasProp = {}.hasOwnProperty,
223
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
224
+ __slice = [].slice;
225
+
226
+ window.Link = (function(_super) {
227
+ __extends(Link, _super);
228
+
229
+ Link.HTML_EXTENSIONS = ['html'];
230
+
231
+ Link.allowExtensions = function() {
232
+ var extension, extensions, _i, _len;
233
+ extensions = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
234
+ for (_i = 0, _len = extensions.length; _i < _len; _i++) {
235
+ extension = extensions[_i];
236
+ Link.HTML_EXTENSIONS.push(extension);
237
+ }
238
+ return Link.HTML_EXTENSIONS;
239
+ };
240
+
241
+ function Link(link) {
242
+ this.link = link;
243
+ if (this.link.constructor === Link) {
244
+ return this.link;
245
+ }
246
+ this.original = this.link.href;
247
+ Link.__super__.constructor.apply(this, arguments);
248
+ }
249
+
250
+ Link.prototype.shouldIgnore = function() {
251
+ return this._crossOrigin() || this._anchored() || this._nonHtml() || this._optOut() || this._target();
252
+ };
253
+
254
+ Link.prototype._crossOrigin = function() {
255
+ return this.origin !== (new ComponentUrl).origin;
256
+ };
257
+
258
+ Link.prototype._anchored = function() {
259
+ var current;
260
+ return ((this.hash && this.withoutHash()) === (current = new ComponentUrl).withoutHash()) || (this.href === current.href + '#');
261
+ };
262
+
263
+ Link.prototype._nonHtml = function() {
264
+ return this.pathname.match(/\.[a-z]+$/g) && !this.pathname.match(new RegExp("\\.(?:" + (Link.HTML_EXTENSIONS.join('|')) + ")?$", 'g'));
265
+ };
266
+
267
+ Link.prototype._optOut = function() {
268
+ var ignore, link;
269
+ link = this.link;
270
+ while (!(ignore || link === document || link === null)) {
271
+ ignore = link.getAttribute('data-no-turbolink') != null;
272
+ link = link.parentNode;
273
+ }
274
+ return ignore;
275
+ };
276
+
277
+ Link.prototype._target = function() {
278
+ return this.link.target.length !== 0;
279
+ };
280
+
281
+ return Link;
282
+
283
+ })(ComponentUrl);
284
+
285
+
286
+
287
+ },{}],6:[function(require,module,exports){
288
+ if (!window.Page) {
289
+ window.Page = {};
290
+ }
291
+
292
+ Page.visit = function(url, opts) {
293
+ if (opts == null) {
294
+ opts = {};
295
+ }
296
+ if (opts.reload) {
297
+ return window.location = url;
298
+ } else {
299
+ return Turbolinks.visit(url);
300
+ }
301
+ };
302
+
303
+ Page.refresh = function(options, callback) {
304
+ var newUrl, paramString;
305
+ if (options == null) {
306
+ options = {};
307
+ }
308
+ newUrl = options.url ? options.url : options.queryParams ? (paramString = $.param(options.queryParams), paramString ? paramString = "?" + paramString : void 0, location.pathname + paramString) : location.href;
309
+ if (options.response) {
310
+ return Turbolinks.loadPage(null, options.response, true, callback, options.onlyKeys || []);
311
+ } else {
312
+ return Turbolinks.visit(newUrl, true, options.onlyKeys || [], function() {
313
+ return typeof callback === "function" ? callback() : void 0;
314
+ });
315
+ }
316
+ };
317
+
318
+ Page.open = function() {
319
+ return window.open.apply(window, arguments);
320
+ };
321
+
322
+
323
+
324
+ },{}],7:[function(require,module,exports){
325
+ window.PageCache = (function() {
326
+ var simultaneousAdditionOffset, storage;
327
+
328
+ storage = {};
329
+
330
+ simultaneousAdditionOffset = 0;
331
+
332
+ function PageCache(cacheSize) {
333
+ this.cacheSize = cacheSize != null ? cacheSize : 10;
334
+ storage = {};
335
+ return this;
336
+ }
337
+
338
+ PageCache.prototype.get = function(key) {
339
+ return storage[key];
340
+ };
341
+
342
+ PageCache.prototype.set = function(key, value) {
343
+ if (typeof value !== "object") {
344
+ throw "Developer error: You must store objects in this cache";
345
+ }
346
+ value['cachedAt'] = new Date().getTime() + (simultaneousAdditionOffset += 1);
347
+ storage[key] = value;
348
+ return this.constrain();
349
+ };
350
+
351
+ PageCache.prototype.clear = function() {
352
+ return storage = {};
353
+ };
354
+
355
+ PageCache.prototype.setCacheSize = function(newSize) {
356
+ if (/^[\d]+$/.test(newSize)) {
357
+ this.cacheSize = parseInt(newSize, 10);
358
+ return this.constrain();
359
+ } else {
360
+ throw "Developer error: Invalid parameter '" + newSize + "' for PageCache; must be integer";
361
+ }
362
+ };
363
+
364
+ PageCache.prototype.constrain = function() {
365
+ var cacheTimesRecentFirst, key, pageCacheKeys, _i, _len, _results;
366
+ pageCacheKeys = Object.keys(storage);
367
+ cacheTimesRecentFirst = pageCacheKeys.map((function(_this) {
368
+ return function(url) {
369
+ return storage[url].cachedAt;
370
+ };
371
+ })(this)).sort(function(a, b) {
372
+ return b - a;
373
+ });
374
+ _results = [];
375
+ for (_i = 0, _len = pageCacheKeys.length; _i < _len; _i++) {
376
+ key = pageCacheKeys[_i];
377
+ if (!(storage[key].cachedAt <= cacheTimesRecentFirst[this.cacheSize])) {
378
+ continue;
379
+ }
380
+ triggerEvent('page:expire', storage[key]);
381
+ _results.push(delete storage[key]);
382
+ }
383
+ return _results;
384
+ };
385
+
386
+ PageCache.prototype.length = function() {
387
+ return Object.keys(storage).length;
388
+ };
389
+
390
+ return PageCache;
391
+
392
+ })();
393
+
394
+
395
+
396
+ },{}],8:[function(require,module,exports){
397
+ TurboGraft.Remote = (function() {
398
+ function Remote(opts, form) {
399
+ var actualRequestType, formData, xhr;
400
+ this.opts = opts;
401
+ if (form) {
402
+ formData = new FormData(form);
403
+ } else {
404
+ formData = new FormData();
405
+ }
406
+ actualRequestType = this.opts.httpRequestType.toLowerCase() === 'get' ? 'GET' : 'POST';
407
+ formData.append("_method", this.opts.httpRequestType);
408
+ if (this.opts.refreshOnSuccess) {
409
+ this.refreshOnSuccess = this.opts.refreshOnSuccess.split(" ");
410
+ }
411
+ if (this.opts.refreshOnError) {
412
+ this.refreshOnError = this.opts.refreshOnError.split(" ");
413
+ }
414
+ xhr = new XMLHttpRequest;
415
+ xhr.open(actualRequestType, this.opts.httpUrl, true);
416
+ xhr.setRequestHeader('Accept', 'text/html, application/xhtml+xml, application/xml');
417
+ xhr.addEventListener('loadstart', function() {
418
+ return triggerEvent('turbograft:remote:start', xhr);
419
+ });
420
+ xhr.addEventListener('error', this.onError);
421
+ xhr.addEventListener('load', (function(_this) {
422
+ return function(event) {
423
+ if (xhr.status < 400) {
424
+ return _this.onSuccess(event);
425
+ } else {
426
+ return _this.onError(event);
427
+ }
428
+ };
429
+ })(this));
430
+ xhr.addEventListener('loadend', function() {
431
+ return triggerEvent('turbograft:remote:always', xhr);
432
+ });
433
+ xhr.send(formData);
434
+ return xhr;
435
+ }
436
+
437
+ Remote.prototype.onSuccess = function(ev) {
438
+ var redirect, xhr;
439
+ xhr = ev.target;
440
+ triggerEvent('turbograft:remote:success', xhr);
441
+ if (redirect = xhr.getResponseHeader('X-Next-Redirect')) {
442
+ Page.visit(redirect, {
443
+ reload: true
444
+ });
445
+ return;
446
+ }
447
+ if (this.opts.fullRefresh) {
448
+ return Page.refresh({
449
+ onlyKeys: this.refreshOnSuccess
450
+ });
451
+ } else if (this.refreshOnSuccess) {
452
+ return Page.refresh({
453
+ response: xhr,
454
+ onlyKeys: this.refreshOnSuccess
455
+ });
456
+ }
457
+ };
458
+
459
+ Remote.prototype.onError = function(ev) {
460
+ var xhr;
461
+ xhr = ev.target;
462
+ triggerEvent('turbograft:remote:fail', xhr);
463
+ if (this.refreshOnError) {
464
+ return Page.refresh({
465
+ response: xhr,
466
+ onlyKeys: this.refreshOnError
467
+ });
468
+ } else {
469
+ return triggerEvent('turbograft:remote:fail:unhandled', xhr);
470
+ }
471
+ };
472
+
473
+ return Remote;
474
+
475
+ })();
476
+
477
+
478
+
479
+ },{}],9:[function(require,module,exports){
480
+ var browserIsntBuggy, browserSupportsCustomEvents, browserSupportsPushState, browserSupportsTurbolinks, historyStateIsDefined, installDocumentReadyPageEventTriggers, installJqueryAjaxSuccessPageUpdateTrigger, popCookie, requestMethodIsSafe, xhr, _ref,
481
+ __slice = [].slice,
482
+ __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
483
+
484
+ xhr = null;
485
+
486
+ installDocumentReadyPageEventTriggers = function() {
487
+ return document.addEventListener('DOMContentLoaded', (function() {
488
+ triggerEvent('page:change');
489
+ return triggerEvent('page:update');
490
+ }), true);
491
+ };
492
+
493
+ installJqueryAjaxSuccessPageUpdateTrigger = function() {
494
+ if (typeof jQuery !== 'undefined') {
495
+ return jQuery(document).on('ajaxSuccess', function(event, xhr, settings) {
496
+ if (!jQuery.trim(xhr.responseText)) {
497
+ return;
498
+ }
499
+ return triggerEvent('page:update');
500
+ });
501
+ }
502
+ };
503
+
504
+ historyStateIsDefined = window.history.state !== void 0 || navigator.userAgent.match(/Firefox\/2[6|7]/);
505
+
506
+ browserSupportsPushState = window.history && window.history.pushState && window.history.replaceState && historyStateIsDefined;
507
+
508
+ browserIsntBuggy = !navigator.userAgent.match(/CriOS\//);
509
+
510
+ window.triggerEvent = function(name, data) {
511
+ var event;
512
+ event = document.createEvent('Events');
513
+ if (data) {
514
+ event.data = data;
515
+ }
516
+ event.initEvent(name, true, true);
517
+ return document.dispatchEvent(event);
518
+ };
519
+
520
+ popCookie = function(name) {
521
+ var value, _ref;
522
+ value = ((_ref = document.cookie.match(new RegExp(name + "=(\\w+)"))) != null ? _ref[1].toUpperCase() : void 0) || '';
523
+ document.cookie = name + '=; expires=Thu, 01-Jan-70 00:00:01 GMT; path=/';
524
+ return value;
525
+ };
526
+
527
+ requestMethodIsSafe = (_ref = popCookie('request_method')) === 'GET' || _ref === '';
528
+
529
+ browserSupportsTurbolinks = browserSupportsPushState && browserIsntBuggy && requestMethodIsSafe;
530
+
531
+ browserSupportsCustomEvents = document.addEventListener && document.createEvent;
532
+
533
+ if (browserSupportsCustomEvents) {
534
+ installDocumentReadyPageEventTriggers();
535
+ installJqueryAjaxSuccessPageUpdateTrigger();
536
+ }
537
+
538
+ window.Turbolinks = (function() {
539
+ var browserCompatibleDocumentParser, bypassOnLoadPopstate, changePage, createDocument, currentState, deleteRefreshNeverNodes, executeScriptTag, executeScriptTags, extractTitleAndBody, fetch, fetchHistory, fetchReplacement, installHistoryChangeHandler, loadedAssets, pageCache, pageChangePrevented, processResponse, recallScrollPosition, referer, reflectNewUrl, reflectRedirectedUrl, refreshNodesWithKeys, rememberReferer, removeNoscriptTags, resetScrollPosition, transitionCacheFor, usePageCache;
540
+
541
+ function Turbolinks() {}
542
+
543
+ createDocument = null;
544
+
545
+ currentState = null;
546
+
547
+ loadedAssets = null;
548
+
549
+ referer = null;
550
+
551
+ usePageCache = false;
552
+
553
+ Turbolinks.pageCache = pageCache = new PageCache();
554
+
555
+ fetch = function(url, partialReplace, replaceContents, callback) {
556
+ var cachedPage;
557
+ if (partialReplace == null) {
558
+ partialReplace = false;
559
+ }
560
+ if (replaceContents == null) {
561
+ replaceContents = [];
562
+ }
563
+ url = new ComponentUrl(url);
564
+ rememberReferer();
565
+ if (usePageCache) {
566
+ Turbolinks.cacheCurrentPage();
567
+ }
568
+ if (usePageCache && (cachedPage = transitionCacheFor(url.absolute))) {
569
+ fetchHistory(cachedPage);
570
+ return fetchReplacement(url, partialReplace, null, replaceContents);
571
+ } else {
572
+ return fetchReplacement(url, partialReplace, function() {
573
+ if (!replaceContents.length) {
574
+ resetScrollPosition();
575
+ }
576
+ return typeof callback === "function" ? callback() : void 0;
577
+ }, replaceContents);
578
+ }
579
+ };
580
+
581
+ Turbolinks.pageCacheEnabled = function() {
582
+ return usePageCache;
583
+ };
584
+
585
+ Turbolinks.usePageCache = function(status) {
586
+ return usePageCache = status;
587
+ };
588
+
589
+ transitionCacheFor = function(url) {
590
+ var cachedPage;
591
+ cachedPage = pageCache.get(url);
592
+ if (cachedPage && !cachedPage.transitionCacheDisabled) {
593
+ return cachedPage;
594
+ }
595
+ };
596
+
597
+ Turbolinks.pushState = function(state, title, url) {
598
+ return window.history.pushState(state, title, url);
599
+ };
600
+
601
+ Turbolinks.replaceState = function(state, title, url) {
602
+ return window.history.replaceState(state, title, url);
603
+ };
604
+
605
+ fetchReplacement = function(url, partialReplace, onLoadFunction, replaceContents) {
606
+ triggerEvent('page:fetch', {
607
+ url: url.absolute
608
+ });
609
+ if (xhr != null) {
610
+ xhr.abort();
611
+ }
612
+ xhr = new XMLHttpRequest;
613
+ xhr.open('GET', url.withoutHashForIE10compatibility(), true);
614
+ xhr.setRequestHeader('Accept', 'text/html, application/xhtml+xml, application/xml');
615
+ xhr.setRequestHeader('X-XHR-Referer', referer);
616
+ xhr.onload = function() {
617
+ if (xhr.status >= 500) {
618
+ return document.location.href = url.absolute;
619
+ } else {
620
+ return Turbolinks.loadPage(url, xhr, partialReplace, onLoadFunction, replaceContents);
621
+ }
622
+ };
623
+ xhr.onloadend = function() {
624
+ return xhr = null;
625
+ };
626
+ xhr.onerror = function() {
627
+ return document.location.href = url.absolute;
628
+ };
629
+ xhr.send();
630
+ };
631
+
632
+ Turbolinks.loadPage = function(url, xhr, partialReplace, onLoadFunction, replaceContents) {
633
+ var doc, nodes;
634
+ if (partialReplace == null) {
635
+ partialReplace = false;
636
+ }
637
+ if (onLoadFunction == null) {
638
+ onLoadFunction = (function() {});
639
+ }
640
+ if (replaceContents == null) {
641
+ replaceContents = [];
642
+ }
643
+ triggerEvent('page:receive');
644
+ if (doc = processResponse(xhr, partialReplace)) {
645
+ reflectNewUrl(url);
646
+ nodes = changePage.apply(null, __slice.call(extractTitleAndBody(doc)).concat([partialReplace], [replaceContents]));
647
+ reflectRedirectedUrl(xhr);
648
+ triggerEvent('page:load', nodes);
649
+ if (typeof onLoadFunction === "function") {
650
+ onLoadFunction();
651
+ }
652
+ } else {
653
+ document.location.href = url.absolute;
654
+ }
655
+ };
656
+
657
+ fetchHistory = function(cachedPage) {
658
+ if (xhr != null) {
659
+ xhr.abort();
660
+ }
661
+ changePage(cachedPage.title, cachedPage.body, false);
662
+ recallScrollPosition(cachedPage);
663
+ return triggerEvent('page:restore');
664
+ };
665
+
666
+ Turbolinks.cacheCurrentPage = function() {
667
+ var currentStateUrl;
668
+ currentStateUrl = new ComponentUrl(currentState.url);
669
+ pageCache.set(currentStateUrl.absolute, {
670
+ url: currentStateUrl.relative,
671
+ body: document.body,
672
+ title: document.title,
673
+ positionY: window.pageYOffset,
674
+ positionX: window.pageXOffset,
675
+ transitionCacheDisabled: document.querySelector('[data-no-transition-cache]') != null
676
+ });
677
+ };
678
+
679
+ changePage = function(title, body, csrfToken, runScripts, partialReplace, replaceContents) {
680
+ if (replaceContents == null) {
681
+ replaceContents = [];
682
+ }
683
+ if (title) {
684
+ document.title = title;
685
+ }
686
+ if (replaceContents.length) {
687
+ return refreshNodesWithKeys(replaceContents, body);
688
+ } else {
689
+ deleteRefreshNeverNodes(body);
690
+ triggerEvent('page:before-replace');
691
+ document.documentElement.replaceChild(body, document.body);
692
+ if (csrfToken != null) {
693
+ CSRFToken.update(csrfToken);
694
+ }
695
+ if (runScripts) {
696
+ executeScriptTags();
697
+ }
698
+ currentState = window.history.state;
699
+ triggerEvent('page:change');
700
+ triggerEvent('page:update');
701
+ }
702
+ };
703
+
704
+ deleteRefreshNeverNodes = function(body) {
705
+ var node, _i, _len, _ref1;
706
+ _ref1 = body.querySelectorAll('[refresh-never]');
707
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
708
+ node = _ref1[_i];
709
+ node.parentNode.removeChild(node);
710
+ }
711
+ };
712
+
713
+ refreshNodesWithKeys = function(keys, body) {
714
+ var allNodesToBeRefreshed, existingNode, key, newNode, node, nodeId, parentIsRefreshing, refreshedNodes, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref1, _ref2;
715
+ allNodesToBeRefreshed = [];
716
+ _ref1 = document.querySelectorAll("[refresh-always]");
717
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
718
+ node = _ref1[_i];
719
+ allNodesToBeRefreshed.push(node);
720
+ }
721
+ for (_j = 0, _len1 = keys.length; _j < _len1; _j++) {
722
+ key = keys[_j];
723
+ _ref2 = document.querySelectorAll("[refresh=" + key + "]");
724
+ for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
725
+ node = _ref2[_k];
726
+ allNodesToBeRefreshed.push(node);
727
+ }
728
+ }
729
+ triggerEvent('page:before-partial-replace', allNodesToBeRefreshed);
730
+ parentIsRefreshing = function(node) {
731
+ var potentialParent, _l, _len3;
732
+ for (_l = 0, _len3 = allNodesToBeRefreshed.length; _l < _len3; _l++) {
733
+ potentialParent = allNodesToBeRefreshed[_l];
734
+ if (node !== potentialParent) {
735
+ if (potentialParent.contains(node)) {
736
+ return true;
737
+ }
738
+ }
739
+ }
740
+ return false;
741
+ };
742
+ refreshedNodes = [];
743
+ for (_l = 0, _len3 = allNodesToBeRefreshed.length; _l < _len3; _l++) {
744
+ existingNode = allNodesToBeRefreshed[_l];
745
+ if (parentIsRefreshing(existingNode)) {
746
+ continue;
747
+ }
748
+ if (!(nodeId = existingNode.getAttribute('id'))) {
749
+ throw new Error("Turbolinks refresh: Refresh key elements must have an id.");
750
+ }
751
+ if (newNode = body.querySelector("#" + nodeId)) {
752
+ existingNode.parentNode.replaceChild(newNode, existingNode);
753
+ if (newNode.nodeName === 'SCRIPT' && newNode.getAttribute("data-turbolinks-eval") !== "false") {
754
+ executeScriptTag(newNode);
755
+ } else {
756
+ refreshedNodes.push(newNode);
757
+ }
758
+ } else if (existingNode.getAttribute("refresh-always") === null) {
759
+ existingNode.parentNode.removeChild(existingNode);
760
+ }
761
+ }
762
+ return refreshedNodes;
763
+ };
764
+
765
+ executeScriptTags = function() {
766
+ var script, scripts, _i, _len, _ref1;
767
+ scripts = Array.prototype.slice.call(document.body.querySelectorAll('script:not([data-turbolinks-eval="false"])'));
768
+ for (_i = 0, _len = scripts.length; _i < _len; _i++) {
769
+ script = scripts[_i];
770
+ if ((_ref1 = script.type) === '' || _ref1 === 'text/javascript') {
771
+ executeScriptTag(script);
772
+ }
773
+ }
774
+ };
775
+
776
+ executeScriptTag = function(script) {
777
+ var attr, copy, nextSibling, parentNode, _i, _len, _ref1;
778
+ copy = document.createElement('script');
779
+ _ref1 = script.attributes;
780
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
781
+ attr = _ref1[_i];
782
+ copy.setAttribute(attr.name, attr.value);
783
+ }
784
+ copy.appendChild(document.createTextNode(script.innerHTML));
785
+ parentNode = script.parentNode, nextSibling = script.nextSibling;
786
+ parentNode.removeChild(script);
787
+ parentNode.insertBefore(copy, nextSibling);
788
+ };
789
+
790
+ removeNoscriptTags = function(node) {
791
+ node.innerHTML = node.innerHTML.replace(/<noscript[\S\s]*?<\/noscript>/ig, '');
792
+ return node;
793
+ };
794
+
795
+ reflectNewUrl = function(url) {
796
+ if ((url = new ComponentUrl(url)).absolute !== referer) {
797
+ Turbolinks.pushState({
798
+ turbolinks: true,
799
+ url: url.absolute
800
+ }, '', url.absolute);
801
+ }
802
+ };
803
+
804
+ reflectRedirectedUrl = function(xhr) {
805
+ var location, preservedHash;
806
+ if (location = xhr.getResponseHeader('X-XHR-Redirected-To')) {
807
+ location = new ComponentUrl(location);
808
+ preservedHash = location.hasNoHash() ? document.location.hash : '';
809
+ Turbolinks.replaceState(currentState, '', location.href + preservedHash);
810
+ }
811
+ };
812
+
813
+ rememberReferer = function() {
814
+ return referer = document.location.href;
815
+ };
816
+
817
+ Turbolinks.rememberCurrentUrl = function() {
818
+ return Turbolinks.replaceState({
819
+ turbolinks: true,
820
+ url: document.location.href
821
+ }, '', document.location.href);
822
+ };
823
+
824
+ Turbolinks.rememberCurrentState = function() {
825
+ return currentState = window.history.state;
826
+ };
827
+
828
+ recallScrollPosition = function(page) {
829
+ return window.scrollTo(page.positionX, page.positionY);
830
+ };
831
+
832
+ resetScrollPosition = function() {
833
+ if (document.location.hash) {
834
+ return document.location.href = document.location.href;
835
+ } else {
836
+ return window.scrollTo(0, 0);
837
+ }
838
+ };
839
+
840
+ pageChangePrevented = function() {
841
+ return !triggerEvent('page:before-change');
842
+ };
843
+
844
+ processResponse = function(xhr, partial) {
845
+ var assetsChanged, changed, clientOrServerError, doc, extractTrackAssets, intersection, validContent;
846
+ if (partial == null) {
847
+ partial = false;
848
+ }
849
+ clientOrServerError = function() {
850
+ var _ref1;
851
+ if (xhr.status === 422) {
852
+ return false;
853
+ }
854
+ return (400 <= (_ref1 = xhr.status) && _ref1 < 600);
855
+ };
856
+ validContent = function() {
857
+ return xhr.getResponseHeader('Content-Type').match(/^(?:text\/html|application\/xhtml\+xml|application\/xml)(?:;|$)/);
858
+ };
859
+ extractTrackAssets = function(doc) {
860
+ var node, _i, _len, _ref1, _results;
861
+ _ref1 = doc.head.childNodes;
862
+ _results = [];
863
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
864
+ node = _ref1[_i];
865
+ if ((typeof node.getAttribute === "function" ? node.getAttribute('data-turbolinks-track') : void 0) != null) {
866
+ _results.push(node.getAttribute('src') || node.getAttribute('href'));
867
+ }
868
+ }
869
+ return _results;
870
+ };
871
+ assetsChanged = function(doc) {
872
+ var fetchedAssets;
873
+ loadedAssets || (loadedAssets = extractTrackAssets(document));
874
+ fetchedAssets = extractTrackAssets(doc);
875
+ return fetchedAssets.length !== loadedAssets.length || intersection(fetchedAssets, loadedAssets).length !== loadedAssets.length;
876
+ };
877
+ intersection = function(a, b) {
878
+ var value, _i, _len, _ref1, _results;
879
+ if (a.length > b.length) {
880
+ _ref1 = [b, a], a = _ref1[0], b = _ref1[1];
881
+ }
882
+ _results = [];
883
+ for (_i = 0, _len = a.length; _i < _len; _i++) {
884
+ value = a[_i];
885
+ if (__indexOf.call(b, value) >= 0) {
886
+ _results.push(value);
887
+ }
888
+ }
889
+ return _results;
890
+ };
891
+ if (!clientOrServerError() && validContent()) {
892
+ doc = createDocument(xhr.responseText);
893
+ changed = assetsChanged(doc);
894
+ if (doc && (!changed || partial)) {
895
+ return doc;
896
+ }
897
+ }
898
+ };
899
+
900
+ extractTitleAndBody = function(doc) {
901
+ var title;
902
+ title = doc.querySelector('title');
903
+ return [title != null ? title.textContent : void 0, removeNoscriptTags(doc.body), CSRFToken.get(doc).token, 'runScripts'];
904
+ };
905
+
906
+ installHistoryChangeHandler = function(event) {
907
+ var cachedPage, _ref1;
908
+ if ((_ref1 = event.state) != null ? _ref1.turbolinks : void 0) {
909
+ if (cachedPage = pageCache.get((new ComponentUrl(event.state.url)).absolute)) {
910
+ Turbolinks.cacheCurrentPage();
911
+ return fetchHistory(cachedPage);
912
+ } else {
913
+ return Turbolinks.visit(event.target.location.href);
914
+ }
915
+ }
916
+ };
917
+
918
+ bypassOnLoadPopstate = function(fn) {
919
+ return setTimeout(fn, 500);
920
+ };
921
+
922
+ browserCompatibleDocumentParser = function() {
923
+ var createDocumentUsingDOM, createDocumentUsingParser, createDocumentUsingWrite, e, testDoc, _ref1;
924
+ createDocumentUsingParser = function(html) {
925
+ return (new DOMParser).parseFromString(html, 'text/html');
926
+ };
927
+ createDocumentUsingDOM = function(html) {
928
+ var doc;
929
+ doc = document.implementation.createHTMLDocument('');
930
+ doc.documentElement.innerHTML = html;
931
+ return doc;
932
+ };
933
+ createDocumentUsingWrite = function(html) {
934
+ var doc;
935
+ doc = document.implementation.createHTMLDocument('');
936
+ doc.open('replace');
937
+ doc.write(html);
938
+ doc.close();
939
+ return doc;
940
+ };
941
+ try {
942
+ if (window.DOMParser) {
943
+ testDoc = createDocumentUsingParser('<html><body><p>test');
944
+ return createDocumentUsingParser;
945
+ }
946
+ } catch (_error) {
947
+ e = _error;
948
+ testDoc = createDocumentUsingDOM('<html><body><p>test');
949
+ return createDocumentUsingDOM;
950
+ } finally {
951
+ if ((testDoc != null ? (_ref1 = testDoc.body) != null ? _ref1.childNodes.length : void 0 : void 0) !== 1) {
952
+ return createDocumentUsingWrite;
953
+ }
954
+ }
955
+ };
956
+
957
+ if (browserSupportsTurbolinks) {
958
+ Turbolinks.visit = fetch;
959
+ Turbolinks.rememberCurrentUrl();
960
+ Turbolinks.rememberCurrentState();
961
+ createDocument = browserCompatibleDocumentParser();
962
+ document.addEventListener('click', Click.installHandlerLast, true);
963
+ bypassOnLoadPopstate(function() {
964
+ return window.addEventListener('popstate', installHistoryChangeHandler, false);
965
+ });
966
+ } else {
967
+ Turbolinks.visit = function(url) {
968
+ return document.location.href = url;
969
+ };
970
+ }
971
+
972
+ return Turbolinks;
973
+
974
+ })();
975
+
976
+
977
+
978
+ },{}]},{},[1,2,3,5,6,7,9,4,8]);
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.1.15
4
+ version: 0.1.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kristian Plettenberg-Dussault
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2015-03-06 00:00:00.000000000 Z
16
+ date: 2015-03-12 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: coffee-rails
@@ -229,6 +229,7 @@ files:
229
229
  - lib/assets/javascripts/turbograft/page.coffee
230
230
  - lib/assets/javascripts/turbograft/remote.coffee
231
231
  - lib/assets/javascripts/turbograft/turbolinks.coffee
232
+ - lib/turbograft.js
232
233
  - lib/turbograft.rb
233
234
  - lib/turbograft/cookies.rb
234
235
  - lib/turbograft/redirection.rb