nette.ajax.js – alt. obsluha pro AJAX s jQuery
- Vojtěch Dobeš
- Gold Partner | 1316
$.nette.ext('confirm', {
before: function (xhr, settings) {
if (!settings.nette) return;
var question = settings.nette.el.data(this.name);
if (question) {
return confirm(question);
}
}
}, {
name: 'ajaxConfirm'
});
Bude fungovat na masteru. Uvažuju, že bych tohle rozšíření mohl dát i přímo do repositáře, jediný problém vidím v tom, že tahle confirmovací funkcionalita může být potřebná i pro neajaxované odkazy. Nevím, jestli je tedy vhodné to svazovat.
- Vojtěch Dobeš
- Gold Partner | 1316
Udělal jsem to s drobnou změnou, takže:
<a n:href="Smazat!" data-ajax-confirm="Opravdu smazat?">Smazat</a>
- LeonardoCA
- Člen | 296
@vojtech.dobes: Jaký je prosím plán dalšího
vývoje pluginu pro history? Potřeboval bych nějakým způsobem vyřešit
history pro signály a přemýšlím z kterého konce na to jít. Používám
signály pro nastavení „view“ komponent a ty url potřebuju mít
v historii.
Jedině bych musel přidat parametry do presenteru a to se mi nechce. Nebo je
ještě jiné řešení?
Editoval LeonardoCA (16. 10. 2012 22:00)
- MW
- Člen | 626
Zdravim,
zda se me velmi sikovny tento js a tak bych rad na nej presel. Muze me prosim jen nekdo poradit, jak na to…
Mam uz nejakou dobu bezici aplikaci a postupem jsem nabalil radu JSek (nektera se tam uz i mozna perou a pochopil jsem, ze tento script by mohl nektere i nahradit) a vzhledem k tomu, ze JS neni moje silna stranka :D … tak prosim o radu, jako blbemu:
Ted nacitam tyto JS v @layoutu
<script type="text/javascript" src="{$basePath}/js/jquery.min.js"></script>
<script type="text/javascript" src="{$basePath}/js/jquery.nette.js"></script>
<script type="text/javascript" src="{$basePath}/js/netteForms.js"></script>
<script type="text/javascript" src="{$basePath}/js/jquery-ui-1.8.11.custom.min.js"></script>
<script type="text/javascript" src="{$basePath}/js/jquery.ui.datepicker-cs.js"></script>
<script type="text/javascript" src="{$basePath}/js/jquery.livequery.js"></script>
<script type="text/javascript" src="{$basePath}/js/jquery.dimensions.js"></script>
<script type="text/javascript" src="{$basePath}/js/jquery.tooltip.js"></script>
<script type="text/javascript" src="{$basePath}/js/jquery.ajaxform.js"></script>
<script type="text/javascript" src="{$basePath}/js/main.js"></script>
<script type="text/javascript" src="{$basePath}/js/jquery.nette.dependentselectbox.js"></script>
<script type="text/javascript" src="{$basePath}/js/grid.js"></script>
Postupne jsem si doupravoval soubor main.js, kde jsem si myslel, ze pridam onen init() dle example.js, ale jakmile to udelam, prestame ne valit jakykoliv ajax (formy, snippety, datepicker..). Obsah main.js:
jQuery(function($){
$('a[data-confirm]').live('click', function(e){
if (!confirm($(this).data('confirm'))) {
e.stopImmediatePropagation();
return false;
}
});
$('input[data-confirm]').live('click', function(e){
if (!confirm($(this).data('confirm'))) {
e.stopImmediatePropagation();
return false;
}
});
$('a.ajax').live('click', function(event){
$.get(this.href);
$("#ajax-spinner").show().css({
position: "absolute",
left: event.pageX - 10,
top: event.pageY - 10
}).ajaxStop(function(){
$(this).hide();
});
return false;
});
$('a.ajaxL').live('click', function(event){
var $li = $(this).closest('li');
$.get(this.href);
$("#ajax-spinner").show().css({
position: "absolute",
left: event.pageX - 10,
top: event.pageY - 10
}).ajaxStop(function(){
$(this).hide();
$li.css('text-decoration', 'line-through');
});
return false;
});
$('a.ajaxTR').live('click', function(event){
var $tr = $(this).closest('tr');
$.get(this.href);
$("#ajax-spinner").show().css({
position: "absolute",
left: event.pageX - 10,
top: event.pageY - 10
}).ajaxStop(function(){
$(this).hide();
$tr.slideUp();
});
return false;
});
$('a.ajaxTD').live('click', function(event){
var $td = $(this).closest('td');
$.get(this.href);
$("#ajax-spinner").show().css({
position: "absolute",
left: event.pageX - 10,
top: event.pageY - 10
}).ajaxStop(function(){
$(this).hide();
$td.slideUp();
});
return false;
});
$('a.ajaxD').live('click', function(event){
var $li = $(this).closest('li');
$.get(this.href);
$("#ajax-spinner").show().css({
position: "absolute",
left: event.pageX - 10,
top: event.pageY - 10
}).ajaxStop(function() {
$(this).hide();
$li.slideUp();
});
return false;
});
$('a.ajaxP').live('click', function(event){
$.get(this.href);
$("#ajax-spinner").show().css({
position: "absolute",
left: event.pageX - 10,
top: event.pageY - 10
}).ajaxStop(function() {
$(this).hide();
});
return false;
});
$("form.ajax :submit").live("click", function ()
{
$(this).ajaxSubmit();
return false;
});
$('<div id="ajax-spinner"></div>').appendTo("body").ajaxStop(function () {
$(this).hide().css({
position: "fixed",
left: "50%",
top: "50%"
});
}).hide();
//$( "input.date" ).datepicker();
$("input.date").live('hover', function(){
$(this).datepicker();
});
$(".tt").tooltip({
showURL: false,
track: true,
delay: 0
});
});
Tak moc prosim o radu, jak to sjednotit a zprovoznit…
Omlouvam se za lamersky dotaz… Do JSka se teprve snazim pronikat…
Predem diky !
Editoval MW (20. 10. 2012 21:15)
- Vojtěch Dobeš
- Gold Partner | 1316
Jen pár doporučení:
- vyhni se
live()
- co děláš pomocí
live()
, dělej normálně, a daný kód umísti do$.nette.ext
do callbacku naload
. - Pro spinner existuje již hotová extenze, zkus se na ni mrknout a kdyžtak si ji nakonfiguruj nebo inspirovaně napiš vlastní.
- Nepotřebuješ bindovat na
a.ajax
Ajaxové volání – to už za tebe dělá$.nette.init
. - Nepoužívej
nette.ajax.js
v kombinaci s jinými Nette pluginy pro AJAX, bude to dělat naprosto logicky bordel.
- Vojtěch Dobeš
- Gold Partner | 1316
Verze 1.2.0
- podpora pro History API (HTML 5) kompletně přepsána a vyčleněna (více info):
$configurator->onCompile[] = function ($configurator, $compiler) {
$compiler->addExtension('ajax', new VojtechDobes\NetteAjax\Extension);
};
- změnilo se API (proto o desetinový řád vyšší číslo verze):
- v
beforeSend
je nyní volána událostbefore
místostart
- událost
start
je volána až po zahájení požadavku - vrácení
false
v událostistart
nic nedělá - obě události
before
astart
dostávají stejné argumenty:jqXHR
(objekt požadavku) asettings
(originální pole parametrů) - ZÁVĚR: v extenzích stačí prohodit
before
astart
callbacky, a změnit hlavičkybefore
callbacků na nové argumenty (původníui
lze najít vsettings.nette.ui
) - v
settings.nette.e
lze nyní najít objekt události
- v
- vzájemná závislost rozšíření je volitelně nepovinná
- lze používat vlastní
beforeSend
callback (viz jQuery API) - pomocí datového atributu
data-ajax-pass
lze zabránit ukončení události, která Ajaxový požadavek vyvolala - opravena kompatibilita s
$form->addDynamic()
(zachovává se pořadí formulářových prvků) - opravy (deklarování anonymních rozšíření, vracení
false
v callbacích nabefore
, CSS pro spinner) - zaktualizována dokumentace
Několik výše uvedených oprav chyb jsem ještě vydal ve verzi 1.1.3, která neobsahuje změnu API.
- Vojtěch Dobeš
- Gold Partner | 1316
@MW Viz instalace, stačí obsah 6. bodu obalit extenzí, cca takto…
$.nette.ext('datepicker', {
load: function () {
$("input.date").each(function () { // input[type=date] does not work in IE
...
});
}
});
- Vojtěch Dobeš
- Gold Partner | 1316
Přidal jsem podporu pro:
- persistentní parametry (pro jejich uchovávání není třeba všechny
odkazy obalovat do snippetů a invaliovat je, nové ajaxové požadavky
vyvolané na původních odkazech budou automaticky o aktuální stav
persistentních parametrů doplněny – jde o dokončení extenze
state
) - infinite scrolling (stačí na snippet přidat zvláštní datový atribut, a jeho obsah se nebude přepisovat, ale jen rozšiřovat)
<ul n:snippet="foo" data-ajax-append>
<li n:foreach="$articles as $article">
{$article->title}
</li>
</ul>
- přidána nová událost
prepare
, volaná ještě předbefore
(její úlohou je upravit objektsettings
, neměla by počítat s tím, že požadavek bude za každých okolností vyvolán – od toho sloužístart
) - při volání
$.nette.ajax()
(resp.$('a').netteAjax()
), lze navěsit callback do událostístart
aprepare
stejně jako do všech klasickýchsuccess
,error
acomplete
, které podporuje už samo jQuery (probefore
lze použít standardníbeforeSend
)
Budu rád za otestování, než to vydám :).
- ji_ri_k
- Člen | 44
Ahoj Vojto,
narazil jsem na jednu drobnost. Cca asi měsíc (bohužel nevím verzi) mi zlobí spinner. Stává se to když formulář neprojde javascriptovou validací (vyskočí alert), spinner se zobrazí ale request už správně neproběhne (spinner se nemá zobrazit). V dřívějších verzích to fungovalo správně.
- tatyalien
- Člen | 239
Prosím možná blbá otázka, ale jak mám docílit, aby stránkování co
mám v komponentě se promítlo i přes ajax v URL? Se starou verzí ajaxu
mě to funguje, s novou ne… routu mám
$container->router[] = new Route(‚[<lang
[a-z]{2}>/]store/<seoTitle>_<department
[0–9]+>[/<goods-paginator-page=0>]‘, ‚Shop:catalog‘);
kde goods-paginator-page odkazuje na komponentu goods, kde je paginator, stránkování v komponentě funguje, ale jak docílit, aby se měnilo id stránky v url?
A ještě jedna věc,
ve staré verzy jsem používal:
(function($, undefined) {
$.nette.ext('spinner', {
init: function () {
spinner = $('<div></div>', { id: "ajax-spinner" });
spinner.appendTo("body");
},
before: function (settings, ui, e) {
$("#ajax-spinner").css({
visibility: "visible",
left: e.pageX,
top: e.pageY
});
},
complete: function () {
$("#ajax-spinner").css({
visibility: "hidden"
});
}
});
})(jQuery);
Jak mám v nové verzy se dostat na element.pageX a Y? Abych mohl zobrazit spinner na správném místě…
Editoval tatyalien (29. 10. 2012 14:38)
- Felix
- Nette Core | 1196
MW napsal(a):
tatyalien napsal(a):
Jak mám v nové verzy se dostat na element.pageX a Y? Abych mohl zobrazit spinner na správném místě…
Také prosím o radu.. jak to správně nastavit…
Je to v prispevku nad vami..
v settings.nette.e lze nyní najít objekt události
Editoval Felix (30. 10. 2012 9:59)
- pekelnik
- Člen | 462
Staci si to precist ;)
(function($, undefined) {
$.nette.ext('spinner', {
init: function () {
spinner = $('<div></div>', { id: "ajax-spinner" });
spinner.appendTo("body");
},
before: function (xhr, settings) {
$("#ajax-spinner").css({
visibility: "visible",
left: settings.nette.e.pageX,
top: settings.nette.e.pageY
});
},
complete: function () {
$("#ajax-spinner").css({
visibility: "hidden"
});
}
});
})(jQuery);
- tatyalien
- Člen | 239
pekelnik: Díky, teď už spinner fachá, jen ještě rozjet to přepisování „url“… Když mám starou verzy doplňku, tak se vše přepisuje správně, pomocí ajaxu se přehodí stránkování a i url se „uměle“ změní… když tam hodím novou verzy, tak stránkování fachá, ale url zůstává beze změny.
- h4kuna
- Backer | 740
Ahoj,
prosím Vás asi jsem to někde přehlédnul a nedaří se mi to nastavit, ale
jak udělám aby po jakémkoliv ajaxu proběhl callback? Potřebuji třeba
zobrazit a schovat flashmessage, teď to dělám tak že si posílám i html
<script>invalidFlashMesagge();</script> což asi posílat nemusím
když už to na stránce mám. Jen zavolat?
- h4kuna
- Backer | 740
Zkusil jsem si implementovat tento doplněk a jen doplním.
vojtech.dobes napsal(a):
<a n:href="Smazat!" data-ajax-confirm="Opravdu smazat?">Smazat</a>
Pro tento případ je potřeba ještě upravit linkSelector
var init = $.nette.ext('init');
init.linkSelector = 'a.ajax, a[data-ajax-confirm]';
a nebo přidat třídu ajax.
<a class="ajax" n:href="Smazat!" data-ajax-confirm="Opravdu smazat?">Smazat</a>
- Lopo
- Člen | 277
h4kuna napsal(a):
Ahoj,
prosím Vás asi jsem to někde přehlédnul a nedaří se mi to nastavit, ale jak udělám aby po jakémkoliv ajaxu proběhl callback? Potřebuji třeba zobrazit a schovat flashmessage, teď to dělám tak že si posílám i html <script>invalidFlashMesagge();</script> což asi posílat nemusím když už to na stránce mám. Jen zavolat?
a totok by ti nepomohlo ? https://github.com/…shMessage.js
- MW
- Člen | 626
duskohu napsal(a):
Zdravim vedeli by ste mi poradit ako teraz vyzera ext. pre:
<a class="ajax" n:href="Smazat!" data-ajax-confirm="Opravdu smazat?">Smazat</a>
Dakujem.
Třeba tak:
$.nette.ext('data-confirm', {
load: function () {
$("a[data-confirm]").click(function (e) {
if (!confirm($(this).data('confirm'))) {
e.stopImmediatePropagation();
return false;
}
});
}
});
- h4kuna
- Backer | 740
Lopo napsal(a):
h4kuna napsal(a):
a totok by ti nepomohlo ? https://github.com/…shMessage.js
Díky mrknu na to.
- Vojtěch Dobeš
- Gold Partner | 1316
tatyalien Ahoj, pro aktualizaci URL s využitím History
API (pokud je dostupné) lze použít novou history
extenzi
sídlící v samostatné složce history
. Kromě javascriptového
souboru je třeba zaregistrovat i VojtechDobes\NetteAjax\Extension
v bootstrapu, aby to fungovalo s co nejméně zásahy do již existujícího
PHP kódu.
- Vojtěch Dobeš
- Gold Partner | 1316
Felix Vypnout konkrétní rozšíření pro konkrétní požadavek lze:
- v případě zajaxovaného elementu mu stačí přidat datový atribut:
<a data-ajax-off="snippets">
- v případě konkrétního volání lze uvést zvláštní parametr:
$.nette.ajax({
off: ['snippets']
});
- h4kuna
- Backer | 740
Prosím Vás docházím do stavu, kdy používám data-ajax-confirm, pak používám jquery sortable, taky přes ajax si posílám pořadí fotek. A jsem zase u toho jak po zmazání obrázku a obnovení snippetu obnovím javascript na sortable? Nemůžu jen skrýt ten obrázek co jsem smazal, ještě tam je stránkování.
- nějak sáhnout do dopňku confirm a doplnit mu volání funkce na obnovení
- mít zásobník/frontu, na úrovni tohoto doplňku nette.ajax, callbacků pro obnovování javascriptu, bylo by univerzální i pro vlastní funkce
- napsat si ten sortable jako extenzi, tady je omezení jen s tímto doplňkem
Nemluvě o tom že někdy nechci aby extenze byla volaná jen s ajaxem viz:
vojtech.dobes napsal(a):
Bude fungovat na masteru. Uvažuju, že bych tohle rozšíření mohl dát i přímo do repositáře, jediný problém vidím v tom, že tahle confirmovací funkcionalita může být potřebná i pro neajaxované odkazy. Nevím, jestli je tedy vhodné to svazovat.
Nějaký doporučení kterou cestou se vydat?
Editoval h4kuna (6. 11. 2012 11:58)
- zopper
- Člen | 20
Je to výborný plugin, ale mám jistý problém: včera jsem jej nainstaloval (staženo z githubu, nette 2.0.6), rozchodil, všechno fungovalo, tak jsem si udělal snapshot a pracoval dál a dnes (tedy, teď už chvilku včera :) ) jsem si všiml, že historie přestala fungovat (ajax funguje dál). První co mě napadlo bylo vrátit se k předchozím verzím a podívat se, co jsem kde změnil, jenže historie nefunguje ani po obnovení toho snapshotu (přitom jsem si nevšiml, že by ten snapshot byl nekompletní, všechno kromě té historie vypadá v pořádku, ale možná jsem si to rozbil vzápětí po rozchození…). Trochu jsem debugoval a dostal se k tomu, že se v payload posílá signal=true a redirect tam není. Pokud invertuju hodnotu payload.signal, tak historie funguje tak jak má… Chování je totožné, ať se procházím v rámci jednoho presenteru, nebo přecházím mezi presentery.
Mohl by mi, prosím, někdo poradit, co by mohlo toto chování
způsobovat?
Rád poskytnu jakékoliv další informace, akorát netuším co by mohlo být
relevantní.
Editoval zopper (10. 11. 2012 1:34)
- zopper
- Člen | 20
@vojtech.dobes S výjimkou zpracování jednoho formuláře, kde chci uživatele přesunout na jinou stránku, manuálně přesměrovávám jen pokud nejde o ajax (ale zkusil jsem to přesměrování zakomentovat, nepomohlo). Jak jsem napsal, kromě samotné historie to funguje v pořádku. Přenáší se opravdu jen ty snippety, které jsou invalidovány (ověřeno, kontrola mě aspoň přiměla upřesnit pár situací, kdy se něco invalidovalo zbytečně :) ) a s tím negovaným signal se všechno chová přesně jak by mělo.
Editoval zopper (10. 11. 2012 17:23)
- Vojtěch Dobeš
- Gold Partner | 1316
@zopper V tom případě přesměrovávej i tehdy, když jde o AJAX. Pokud máš zaregistrovanou tu AjaxExtension, tak si to s tím poradí… jinak pokud v signálu nepřesměruješ, tak se ten signál do historie neuloží, protože po každém signálu má stejně nastat přesměrování.
- Vojtěch Dobeš
- Gold Partner | 1316
@zopper Podívej se na to takto: po signálu má nastat přesměrování, jak sám říkáš, tak mimo AJAX by jsi provedl redirect. Správně by to mělo proběhnout i při AJAXu. Provede se to tedy tak, že ty zavoláš redirect, a nazpět se pošlou snippety invalidované až v té výsledné stránce „po redirectu“.
- zopper
- Člen | 20
@vojtech.dobes Hmm, tak jsem to zkusil, ale buď to
dávám na špatná místa (zkusil jsem startup(), beforeRender() i někam do
action), nebo je problém někde jinde – adresa se sice skutečně mění,
ale pro změnu se nepřenáší obsah. :(
PS: na správné nastavení té upravené podmínky pro payload jsem
nezapoměl
EDIT: tím nepřenáší myslím, že v payloadu není žádný snippet
Editoval zopper (10. 11. 2012 19:47)
- Vojtěch Dobeš
- Gold Partner | 1316
Bude asi třeba invalidovat obecně content v beforeRender v nějakém Basepresenteru.
- Siam
- Člen | 54
Psal jsem to na github, ale nikdo nereagoval.
Hází mi to v konzoli tento error:
<script>
TypeError: function (a) {var b = "[data-dismiss=\"alert\"]", c = function (c) {a(c).on("click", b, this.close);};c.prototype.close = function (b) {
function f() {e.trigger("closed").remove();}
var c = a(this), d = c.attr("data-target"), e;d || (d = c.attr("href"), d = d && d.replace(/.*(?=#[^\s]*$)/, "")), e = a(d), b && b.preventDefault(), e.length || (e = c.hasClass("alert") ? c : c.parent()), e.trigger(b = a.Event("close"));if (b.isDefaultPrevented()) {return;}e.removeClass("in"), a.support.transition && e.hasClass("fade") ? e.on(a.support.transition.end, f) : f();}, a.fn.alert = function (b) {return this.each(function () {var d = a(this), e = d.data("alert");e || d.data("alert", e = new c(this)), typeof b == "string" && e[b].call(d);});}, a.fn.alert.Constructor = c, a(function () {a("body").on("click.alert.data-api", b, c.prototype.close);});}(window.jQuery) is not a function
</script>
Používám twitter bootstrap a náhodou jsem zjistil, že tam je nějaká twb větev, tak zkusil jí, ale ta mi také nejde a nehlásí žádnou chybu. Projevuje se to tak, že se místo ajax požadavku normálně přesměruje.
Předtím jsem používal script od Honzy Marka, který funguje bez problémů. Odkazy mají třídu ajax a zalinkovaný je to js také správně. Čím to může být?
Editoval Siam (10. 11. 2012 20:17)
- Vojtěch Dobeš
- Gold Partner | 1316
Nahoď související HTML, JS, ať se to dá trochu debugovat. Takhle těžko pátrat…
- Siam
- Člen | 54
vojtech.dobes:
když označím na stránce nějaký text a pak kliknu na ten odkaz, tak se
v adresním řádku změní adresa, ve firebugu vidím, že byl poslaný
i správný snippet a ten označený text je stále označený, takže ten
problém je asi akorát v té adrese…
Na email jsem ti poslal staženou stránku z localhostu, tak tam prosím mrkni.
- zopper
- Člen | 20
Tak se mi to pořád vyřešit nepodařilo, ať jsem to zkusil dát kamkoliv, zatím tedy nechávám invertovanou hodnotu a později se na to zase podívám (možná to zkusím nasimulovat na čistém sandboxu).
Našel jsem ale problém s informací uvedenou v readme na githubu –
<title n:inner-snippet="title">...
je podle všeho nevhodné,
v IE8 na tom skončí celý skript, když IE zahlásí neočekávaný přístup
k vlastnosti (editace tagu přes DOM). Podle diskuze na jquery.com by měl být
title měněný pouze přes document.title = "nový titulek"
.
Přemýšlím tedy, jak to nejsnáz vyřešit – zřejmě vložit hodnotu do
payload (dá se nějak ze snippetu ještě v php vytáhnout obsah a zrušit
jeho zaslání? Nebo spíš sestavit titulek ještě v presenteru a do šablony
už jen natvrdo vypsat hodnotu, bez možnosti úpravy?) a manuálně ten titulek
nastavit.
EDIT: Aha, tak s tím title to sice je v nette.ajax.js
řešené, ale řekl bych, že špatně – kolem řádku 350, updateSnippet:
if ($el.eq(0).tagName == 'TITLE' )
nefunguje, tagName je vždy
undefined.
Správně by mělo být $el.eq(0)[0].tagName
, pak ta podmínka
funguje jak má.
EDIT2: Tak po delším experimentování napříč různými verzemi IE jsem to upravil takto:
var tagName = ""; // because some elements don't have tagName
if(typeof $el.eq(0).tagName != "undefined"){
// IE 9
tagName = $el.eq(0).tagName;
}else if(typeof $el.eq(0)[0] != "undefined"){
// IE 8
tagName = $el.eq(0)[0].tagName;
}
if (tagName == 'TITLE' ) {...
Testoval jsem to, na čem jsem mohl a v této podobě to prošlo všude.
Mimochodem, zjistil jsem, že u IE 9 se mi vůbec nemění adresa (u IE 8 se ajax neprovádí a spadne to na normální načtení, což je ok, ale IE 9 je v jakémsi divném mezistavu) a u Opery se nemění, pokud došlo ke změně parametru náležejícícho komponentě, nikoliv presenteru. Payload vypadá v pořádku, jako kdekoliv jinde.
Editoval zopper (11. 11. 2012 20:25)
- Vojtěch Dobeš
- Gold Partner | 1316
@zopper Zatím jsem neměl čas se do toho pustit, ale díky za report, update titlu jsem opravil.
- Vojtěch Dobeš
- Gold Partner | 1316
@zopper Díky za úpravu, ale již jsem to opravil. Je ta oprava nedostatečná?
Ohledně dalších bugů, nechceš je reportovat na Githubu? Tady je to mišmaš a nejsem schopen sledovat jednotlivá vlákna procházející skrze příspěvky…
- zopper
- Člen | 20
vojtech.dobes: No, ta moje první úprava to zprovoznila v IE 8, ale v IE 9 to rozbila a já si toho hned nevšiml. :-[ Proto je tam teď ta podmínka. Testoval jsem to takhle jak v IE 9, tak v IE 8, tak v Chrome, Firefoxu i Opeře (nejnovějších verzích) a všude to funguje, takže to snad je správně.
Další věci teda zkusím přímo přes github, pokud něco najdu. :)
Momentálně jsem se ale na IE naštval a všechno co neumí history.pushState
se musí obejít bez ajaxu. :D