summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorschneefux <schneefux+commit@schneefux.xyz>2016-06-07 18:41:26 +0200
committerschneefux <schneefux+commit@schneefux.xyz>2016-06-07 18:41:26 +0200
commitfad28e744605c645c2d98e7a885e49dc498c974f (patch)
treef0cfc7b190f65a9539202d79303136e2c98f4415
parent5524001fac49e981ecf11086abf2bc0838f11ef0 (diff)
downloadjokevote-fad28e744605c645c2d98e7a885e49dc498c974f.tar.gz
jokevote-fad28e744605c645c2d98e7a885e49dc498c974f.zip
smoothstate: honor redirects (merged pr 267)
-rw-r--r--app.py5
-rw-r--r--static/smoothstate.min.js47
-rw-r--r--templates/index.html2
3 files changed, 43 insertions, 11 deletions
diff --git a/app.py b/app.py
index 29e5543..7f835ca 100644
--- a/app.py
+++ b/app.py
@@ -7,6 +7,7 @@ from config import config
from flask import (
Flask,
render_template,
+ make_response,
Markup,
request,
g,
@@ -302,7 +303,9 @@ def page(num):
if 'userlogin' in session:
user['loggedin'] = True
user['name'] = session['userlogin']
- return render_template('index.html', currentpage=num, pages=[[]]*numpages, jokes=jokes, user=user)
+ r = make_response(render_template('index.html', currentpage=num, pages=[[]]*numpages, jokes=jokes, user=user))
+ r.headers.set('X-SmoothState-Location', request.path)
+ return r
@app.route('/submit', methods=['POST'])
def submit():
diff --git a/static/smoothstate.min.js b/static/smoothstate.min.js
index cfb52b8..3412a96 100644
--- a/static/smoothstate.min.js
+++ b/static/smoothstate.min.js
@@ -1,9 +1,38 @@
-/*!
- * smoothState.js is jQuery plugin that progressively enhances
- * page loads to behave more like a single-page application.
- *
- * @author Miguel Ángel Pérez reachme@miguel-perez.com
- * @see http://smoothstate.com
- *
- */
-!function(t){"use strict";"object"==typeof module&&"object"==typeof module.exports?t(require("jquery"),window,document):t(jQuery,window,document)}(function(t,e,n,o){"use strict";if(!e.history.pushState)return t.fn.smoothState=function(){return this},void(t.fn.smoothState.options={});if(!t.fn.smoothState){var r=t("html, body"),a=e.console,i={debug:!1,anchors:"a",hrefRegex:"",forms:"form",allowFormCaching:!1,repeatDelay:500,blacklist:".no-smoothState",prefetch:!1,prefetchOn:"mouseover touchstart",prefetchBlacklist:".no-prefetch",cacheLength:0,loadingClass:"is-loading",scroll:!0,alterRequest:function(t){return t},alterChangeState:function(t,e,n){return t},onBefore:function(t,e){},onStart:{duration:0,render:function(t){}},onProgress:{duration:0,render:function(t){}},onReady:{duration:0,render:function(t,e){t.html(e)}},onAfter:function(t,e){}},s={isExternal:function(t){var n=t.match(/^([^:\/?#]+:)?(?:\/\/([^\/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/);return"string"==typeof n[1]&&n[1].length>0&&n[1].toLowerCase()!==e.location.protocol?!0:"string"==typeof n[2]&&n[2].length>0&&n[2].replace(new RegExp(":("+{"http:":80,"https:":443}[e.location.protocol]+")?$"),"")!==e.location.host},stripHash:function(t){return t.replace(/#.*/,"")},isHash:function(t,n){n=n||e.location.href;var o=t.indexOf("#")>-1,r=s.stripHash(t)===s.stripHash(n);return o&&r},translate:function(e){var n={dataType:"html",type:"GET"};return e="string"==typeof e?t.extend({},n,{url:e}):t.extend({},n,e)},shouldLoadAnchor:function(t,e,n){var r=t.prop("href");return!(s.isExternal(r)||s.isHash(r)||t.is(e)||t.prop("target")||typeof n!==o&&""!==n&&-1===t.prop("href").search(n))},clearIfOverCapacity:function(t,e){return Object.keys||(Object.keys=function(t){var e,n=[];for(e in t)Object.prototype.hasOwnProperty.call(t,e)&&n.push(e);return n}),Object.keys(t).length>e&&(t={}),t},storePageIn:function(e,n,o,r,a){var i=t("<html></html>").append(t(o));return e[n]={status:"loaded",title:i.find("title").first().text(),html:i.find("#"+r),doc:o,state:a},e},triggerAllAnimationEndEvent:function(e,n){n=" "+n||"";var o=0,r="animationstart webkitAnimationStart oanimationstart MSAnimationStart",a="animationend webkitAnimationEnd oanimationend MSAnimationEnd",i="allanimationend",l=function(n){t(n.delegateTarget).is(e)&&(n.stopPropagation(),o++)},u=function(n){t(n.delegateTarget).is(e)&&(n.stopPropagation(),o--,0===o&&e.trigger(i))};e.on(r,l),e.on(a,u),e.on("allanimationend"+n,function(){o=0,s.redraw(e)})},redraw:function(t){t.height()}},l=function(n){if(null!==n.state){var o=e.location.href,r=t("#"+n.state.id),a=r.data("smoothState"),i=a.href!==o&&!s.isHash(o,a.href),l=n.state!==a.cache[a.href].state;(i||l)&&(l&&a.clear(a.href),a.load(o,!1))}},u=function(i,l){var u=t(i),c=u.prop("id"),f=null,h=!1,d={},p={},g=e.location.href,m=function(t){t=t||!1,t&&d.hasOwnProperty(t)?delete d[t]:d={},u.data("smoothState").cache=d},y=function(e,n){n=n||t.noop;var o=s.translate(e);if(d=s.clearIfOverCapacity(d,l.cacheLength),!d.hasOwnProperty(o.url)||"undefined"!=typeof o.data){d[o.url]={status:"fetching"};var r=t.ajax(o);r.done(function(t){s.storePageIn(d,o.url,t,c),u.data("smoothState").cache=d}),r.fail(function(){d[o.url].status="error"}),n&&r.always(n)}},v=function(){if(f){var e=t(f,u);if(e.length){var n=e.offset().top;r.scrollTop(n)}f=null}},S=function(o){var i="#"+c,s=d[o]?t(d[o].html.html()):null;s.length?(n.title=d[o].title,u.data("smoothState").href=o,l.loadingClass&&r.removeClass(l.loadingClass),l.onReady.render(u,s),u.one("ss.onReadyEnd",function(){h=!1,l.onAfter(u,s),l.scroll&&v(),O(u)}),e.setTimeout(function(){u.trigger("ss.onReadyEnd")},l.onReady.duration)):!s&&l.debug&&a?a.warn("No element with an id of "+i+" in response from "+o+" in "+d):e.location=o},w=function(t,n,o){var i=s.translate(t);"undefined"==typeof n&&(n=!0),"undefined"==typeof o&&(o=!0);var f=!1,h=!1,g={loaded:function(){var t=f?"ss.onProgressEnd":"ss.onStartEnd";h&&f?h&&S(i.url):u.one(t,function(){S(i.url),o||m(i.url)}),n&&(p=l.alterChangeState({id:c},d[i.url].title,i.url),d[i.url].state=p,e.history.pushState(p,d[i.url].title,i.url)),h&&!o&&m(i.url)},fetching:function(){f||(f=!0,u.one("ss.onStartEnd",function(){l.loadingClass&&r.addClass(l.loadingClass),l.onProgress.render(u),e.setTimeout(function(){u.trigger("ss.onProgressEnd"),h=!0},l.onProgress.duration)})),e.setTimeout(function(){d.hasOwnProperty(i.url)&&g[d[i.url].status]()},10)},error:function(){l.debug&&a?a.log("There was an error loading: "+i.url):e.location=i.url}};d.hasOwnProperty(i.url)||y(i),l.onStart.render(u),e.setTimeout(function(){l.scroll&&r.scrollTop(0),u.trigger("ss.onStartEnd")},l.onStart.duration),g[d[i.url].status]()},E=function(e){var n,o=t(e.currentTarget);s.shouldLoadAnchor(o,l.blacklist,l.hrefRegex)&&!h&&(e.stopPropagation(),n=s.translate(o.prop("href")),n=l.alterRequest(n),y(n))},b=function(e){var n=t(e.currentTarget);if(!e.metaKey&&!e.ctrlKey&&s.shouldLoadAnchor(n,l.blacklist,l.hrefRegex)&&(e.stopPropagation(),e.preventDefault(),!T())){A();var o=s.translate(n.prop("href"));h=!0,f=n.prop("hash"),o=l.alterRequest(o),l.onBefore(n,u),w(o)}},C=function(e){var n=t(e.currentTarget);if(!n.is(l.blacklist)&&(e.preventDefault(),e.stopPropagation(),!T())){A();var r={url:n.prop("action"),data:n.serialize(),type:n.prop("method")};h=!0,r=l.alterRequest(r),"get"===r.type.toLowerCase()&&(r.url=r.url+"?"+r.data),l.onBefore(n,u),w(r,o,l.allowFormCaching)}},P=0,T=function(){var t=null===l.repeatDelay,e=parseInt(Date.now())>P;return!(t||e)},A=function(){P=parseInt(Date.now())+parseInt(l.repeatDelay)},O=function(t){l.anchors&&l.prefetch&&t.find(l.anchors).not(l.prefetchBlacklist).on(l.prefetchOn,null,E)},x=function(t){l.anchors&&(t.on("click",l.anchors,b),O(t)),l.forms&&t.on("submit",l.forms,C)},R=function(){var t=u.prop("class");u.removeClass(t),s.redraw(u),u.addClass(t)};return l=t.extend({},t.fn.smoothState.options,l),null===e.history.state?(p=l.alterChangeState({id:c},n.title,g),e.history.replaceState(p,n.title,g)):p={},s.storePageIn(d,g,n.documentElement.outerHTML,c,p),s.triggerAllAnimationEndEvent(u,"ss.onStartEnd ss.onProgressEnd ss.onEndEnd"),x(u),{href:g,cache:d,clear:m,load:w,fetch:y,restartCSSAnimations:R}},c=function(e){return this.each(function(){var n=this.tagName.toLowerCase();this.id&&"body"!==n&&"html"!==n&&!t.data(this,"smoothState")?t.data(this,"smoothState",new u(this,e)):!this.id&&a?a.warn("Every smoothState container needs an id but the following one does not have one:",this):"body"!==n&&"html"!==n||!a||a.warn("The smoothstate container cannot be the "+this.tagName+" tag")})};e.onpopstate=l,t.smoothStateUtility=s,t.fn.smoothState=c,t.fn.smoothState.options=i}}); \ No newline at end of file
+/*!* smoothState.js is jQuery plugin that progressively enhances
+* page loads to behave more like a single-page application.
+*
+* @author Miguel Ángel Pérez reachme@miguel-perez.com
+* @see http://smoothstate.com
+**/(function(factory){'use strict';if(typeof module==='object'&&typeof module.exports==='object'){factory(require('jquery'),window,document);}else{factory(jQuery,window,document);}}(function($,window,document,undefined){'use strict';if(!window.history.pushState){$.fn.smoothState=function(){return this;};$.fn.smoothState.options={};return;}
+if($.fn.smoothState){return;}
+var
+$body=$('html, body'),consl=window.console,defaults={debug:false,anchors:'a',hrefRegex:'',forms:'form',allowFormCaching:false,repeatDelay:500,blacklist:'.no-smoothState',prefetch:false,prefetchOn:'mouseover touchstart',prefetchBlacklist:'.no-prefetch',locationHeader:'X-SmoothState-Location',cacheLength:0,loadingClass:'is-loading',scroll:true,alterRequest:function(request){return request;},alterChangeState:function(state,title,url){return state;},onBefore:function($currentTarget,$container){},onStart:{duration:0,render:function($container){}},onProgress:{duration:0,render:function($container){}},onReady:{duration:0,render:function($container,$newContent){$container.html($newContent);}},onAfter:function($container,$newContent){}},utility={isExternal:function(url){var match=url.match(/^([^:\/?#]+:)?(?:\/\/([^\/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/);if(typeof match[1]==='string'&&match[1].length>0&&match[1].toLowerCase()!==window.location.protocol){return true;}
+if(typeof match[2]==='string'&&match[2].length>0&&match[2].replace(new RegExp(':('+{'http:':80,'https:':443}[window.location.protocol]+')?$'),'')!==window.location.host){return true;}
+return false;},stripHash:function(href){return href.replace(/#.*/,'');},isHash:function(href,prev){prev=prev||window.location.href;var hasHash=(href.indexOf('#')>-1)?true:false,samePath=(utility.stripHash(href)===utility.stripHash(prev))?true:false;return(hasHash&&samePath);},translate:function(request){var defaults={dataType:'html',type:'GET'};if(typeof request==='string'){request=$.extend({},defaults,{url:request});}else{request=$.extend({},defaults,request);}
+return request;},shouldLoadAnchor:function($anchor,blacklist,hrefRegex){var href=$anchor.prop('href');return(!utility.isExternal(href)&&!utility.isHash(href)&&!$anchor.is(blacklist)&&!$anchor.prop('target'))&&(typeof hrefRegex===undefined||hrefRegex===''||$anchor.prop('href').search(hrefRegex)!==-1);},clearIfOverCapacity:function(cache,cap){if(!Object.keys){Object.keys=function(obj){var keys=[],k;for(k in obj){if(Object.prototype.hasOwnProperty.call(obj,k)){keys.push(k);}}
+return keys;};}
+if(Object.keys(cache).length>cap){cache={};}
+return cache;},storePageIn:function(object,url,doc,id,state,destUrl){var $html=$('<html></html>').append($(doc));if(typeof state==='undefined'){state={};}
+if(typeof destUrl==='undefined'){destUrl=url;}
+object[url]={status:'loaded',title:$html.find('title').first().text(),html:$html.find('#'+id),doc:doc,state:state,destUrl:destUrl};return object;},triggerAllAnimationEndEvent:function($element,resetOn){resetOn=' '+resetOn||'';var animationCount=0,animationstart='animationstart webkitAnimationStart oanimationstart MSAnimationStart',animationend='animationend webkitAnimationEnd oanimationend MSAnimationEnd',eventname='allanimationend',onAnimationStart=function(e){if($(e.delegateTarget).is($element)){e.stopPropagation();animationCount++;}},onAnimationEnd=function(e){if($(e.delegateTarget).is($element)){e.stopPropagation();animationCount--;if(animationCount===0){$element.trigger(eventname);}}};$element.on(animationstart,onAnimationStart);$element.on(animationend,onAnimationEnd);$element.on('allanimationend'+resetOn,function(){animationCount=0;utility.redraw($element);});},redraw:function($element){$element.height();}},onPopState=function(e){if(e.state!==null){var url=window.location.href,$page=$('#'+e.state.id),page=$page.data('smoothState'),diffUrl=(page.href!==url&&!utility.isHash(url,page.href)),diffState=(e.state!==page.cache[page.href].state);if(diffUrl||diffState){if(diffState){page.clear(page.href);}
+page.load(url,false);}}},Smoothstate=function(element,options){var
+$container=$(element),elementId=$container.prop('id'),targetHash=null,isTransitioning=false,cache={},state={},currentHref=window.location.href,clear=function(url){url=url||false;if(url&&cache.hasOwnProperty(url)){delete cache[url];}else{cache={};}
+$container.data('smoothState').cache=cache;},fetch=function(request,callback){callback=callback||$.noop;var settings=utility.translate(request);cache=utility.clearIfOverCapacity(cache,options.cacheLength);if(cache.hasOwnProperty(settings.url)&&typeof settings.data==='undefined'){return;}
+cache[settings.url]={status:'fetching'};var ajaxRequest=$.ajax(settings);ajaxRequest.done(function(html){utility.storePageIn(cache,settings.url,html,elementId);$container.data('smoothState').cache=cache;});ajaxRequest.fail(function(){cache[settings.url].status='error';});if(options.locationHeader){ajaxRequest.always(function(htmlOrXhr,status,errorOrXhr){var xhr=(htmlOrXhr.statusCode?htmlOrXhr:errorOrXhr),redirectedLocation=xhr.getResponseHeader(options.locationHeader);if(redirectedLocation){cache[settings.url].destUrl=redirectedLocation;}});}
+if(callback){ajaxRequest.always(callback);}},repositionWindow=function(){if(targetHash){var $targetHashEl=$(targetHash,$container);if($targetHashEl.length){var newPosition=$targetHashEl.offset().top;$body.scrollTop(newPosition);}
+targetHash=null;}},updateContent=function(url){var containerId='#'+elementId,$newContent=cache[url]?$(cache[url].html.html()):null;if($newContent.length){document.title=cache[url].title;$container.data('smoothState').href=url;if(options.loadingClass){$body.removeClass(options.loadingClass);}
+options.onReady.render($container,$newContent);$container.one('ss.onReadyEnd',function(){isTransitioning=false;options.onAfter($container,$newContent);if(options.scroll){repositionWindow();}
+bindPrefetchHandlers($container);});window.setTimeout(function(){$container.trigger('ss.onReadyEnd');},options.onReady.duration);}else if(!$newContent&&options.debug&&consl){consl.warn('No element with an id of '+containerId+' in response from '+url+' in '+cache);}else{window.location=url;}},load=function(request,push,cacheResponse){var settings=utility.translate(request);if(typeof push==='undefined'){push=true;}
+if(typeof cacheResponse==='undefined'){cacheResponse=true;}
+var
+hasRunCallback=false,callbBackEnded=false,responses={loaded:function(){var eventName=hasRunCallback?'ss.onProgressEnd':'ss.onStartEnd';if(!callbBackEnded||!hasRunCallback){$container.one(eventName,function(){updateContent(settings.url);if(!cacheResponse){clear(settings.url);}});}
+else if(callbBackEnded){updateContent(settings.url);}
+if(push){var destUrl=cache[settings.url].destUrl;state=options.alterChangeState({id:elementId},cache[settings.url].title,destUrl);cache[settings.url].state=state;window.history.pushState(state,cache[settings.url].title,destUrl);}
+if(callbBackEnded&&!cacheResponse){clear(settings.url);}},fetching:function(){if(!hasRunCallback){hasRunCallback=true;$container.one('ss.onStartEnd',function(){if(options.loadingClass){$body.addClass(options.loadingClass);}
+options.onProgress.render($container);window.setTimeout(function(){$container.trigger('ss.onProgressEnd');callbBackEnded=true;},options.onProgress.duration);});}
+window.setTimeout(function(){if(cache.hasOwnProperty(settings.url)){responses[cache[settings.url].status]();}},10);},error:function(){if(options.debug&&consl){consl.log('There was an error loading: '+settings.url);}else{window.location=settings.url;}}};if(!cache.hasOwnProperty(settings.url)){fetch(settings);}
+options.onStart.render($container);window.setTimeout(function(){if(options.scroll){$body.scrollTop(0);}
+$container.trigger('ss.onStartEnd');},options.onStart.duration);responses[cache[settings.url].status]();},hoverAnchor=function(event){var request,$anchor=$(event.currentTarget);if(utility.shouldLoadAnchor($anchor,options.blacklist,options.hrefRegex)&&!isTransitioning){event.stopPropagation();request=utility.translate($anchor.prop('href'));request=options.alterRequest(request);fetch(request);}},clickAnchor=function(event){var $anchor=$(event.currentTarget);if(!event.metaKey&&!event.ctrlKey&&utility.shouldLoadAnchor($anchor,options.blacklist,options.hrefRegex)){event.stopPropagation();event.preventDefault();if(!isRateLimited()){setRateLimitRepeatTime();var request=utility.translate($anchor.prop('href'));isTransitioning=true;targetHash=$anchor.prop('hash');request=options.alterRequest(request);options.onBefore($anchor,$container);load(request);}}},submitForm=function(event){var $form=$(event.currentTarget);if(!$form.is(options.blacklist)){event.preventDefault();event.stopPropagation();if(!isRateLimited()){setRateLimitRepeatTime();var request={url:$form.prop('action'),data:$form.serialize(),type:$form.prop('method')};isTransitioning=true;request=options.alterRequest(request);if(request.type.toLowerCase()==='get'){request.url=request.url+'?'+request.data;}
+options.onBefore($form,$container);load(request,undefined,options.allowFormCaching);}}},rateLimitRepeatTime=0,isRateLimited=function(){var isFirstClick=(options.repeatDelay===null);var isDelayOver=(parseInt(Date.now())>rateLimitRepeatTime);return!(isFirstClick||isDelayOver);},setRateLimitRepeatTime=function(){rateLimitRepeatTime=parseInt(Date.now())+parseInt(options.repeatDelay);},bindPrefetchHandlers=function($element){if(options.anchors&&options.prefetch){$element.find(options.anchors).not(options.prefetchBlacklist).on(options.prefetchOn,null,hoverAnchor);}},bindEventHandlers=function($element){if(options.anchors){$element.on('click',options.anchors,clickAnchor);bindPrefetchHandlers($element);}
+if(options.forms){$element.on('submit',options.forms,submitForm);}},restartCSSAnimations=function(){var classes=$container.prop('class');$container.removeClass(classes);utility.redraw($container);$container.addClass(classes);};options=$.extend({},$.fn.smoothState.options,options);if(window.history.state===null){state=options.alterChangeState({id:elementId},document.title,currentHref);window.history.replaceState(state,document.title,currentHref);}else{state={};}
+utility.storePageIn(cache,currentHref,document.documentElement.outerHTML,elementId,state);utility.triggerAllAnimationEndEvent($container,'ss.onStartEnd ss.onProgressEnd ss.onEndEnd');bindEventHandlers($container);return{href:currentHref,cache:cache,clear:clear,load:load,fetch:fetch,restartCSSAnimations:restartCSSAnimations};},declaresmoothState=function(options){return this.each(function(){var tagname=this.tagName.toLowerCase();if(this.id&&tagname!=='body'&&tagname!=='html'&&!$.data(this,'smoothState')){$.data(this,'smoothState',new Smoothstate(this,options));}else if(!this.id&&consl){consl.warn('Every smoothState container needs an id but the following one does not have one:',this);}else if((tagname==='body'||tagname==='html')&&consl){consl.warn('The smoothstate container cannot be the '+this.tagName+' tag');}});};window.onpopstate=onPopState;$.smoothStateUtility=utility;$.fn.smoothState=declaresmoothState;$.fn.smoothState.options=defaults;})); \ No newline at end of file
diff --git a/templates/index.html b/templates/index.html
index d0b1292..cdbb1b5 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -141,7 +141,7 @@
</div>
<script type="text/javascript">
$(document).ready(function() {
- $('#main').smoothState({prefetch: true});
+ $('#main').smoothState({prefetch: true, locationHeader: 'X-SmoothState-Location'});
});
function openEditor(me) {
var joke = $(me).closest('.joke');