Skip to content

Instantly share code, notes, and snippets.

@maple3142
Last active April 20, 2018 12:54
Show Gist options
  • Save maple3142/d9c752cebfdd92a7edd1e59ea2cd2f6a to your computer and use it in GitHub Desktop.
Save maple3142/d9c752cebfdd92a7edd1e59ea2cd2f6a to your computer and use it in GitHub Desktop.
(function(global) {
'use strict'
const pjax={}
pjax._get=url=>{
return new Promise((res,rej)=>{
const xhr=new XMLHttpRequest()
xhr.open('GET', url)
xhr.onload=()=>res([xhr.responseText,xhr])
xhr.onerror=rej
xhr.send()
})
}
pjax._loadJS=e=>{
pjax.trigger('loadjs:before')
return new Promise((res,rej)=>{
const s=document.createElement('script')
s.onload=res
s.onerror=res
if(e.src)s.src=e.src
else{
s.textContent=e.textContent
setTimeout(()=>res(),0)
}
document.body.appendChild(s)
}).then(()=>pjax.trigger('loadjs:after'))
}
pjax._loadPage=(url,loadjs)=>{
pjax.trigger('loadpage:before')
return pjax._get(url).then(([html,xhr])=>{
if(xhr.getResponseHeader('Content-Type').indexOf('text/html')===-1){
location.href=url
return
}
const doc=document.implementation.createHTMLDocument('')
doc.documentElement.innerHTML=html
const scripts=Array.from(doc.querySelectorAll('script')).map(e=>(e.remove(),e))
window.scripts=scripts
document.body=doc.body
document.title=doc.title
pjax.trigger('loadpage:after')
if(loadjs)scripts.reduce((p,s)=>p.then(()=>pjax._loadJS(s)),Promise.resolve()).catch(console.error)
}).catch(()=>location.href=url)
}
pjax._parentMatch=(el,test)=>el?((test(el)&&el)||pjax._parentMatch(el.parentNode,test)):false
pjax._on={}
pjax._on.click=({match,loadjs})=>e=>{
let el
if(!(el=pjax._parentMatch(e.target,match))){
return
}
e.preventDefault()
e.stopPropagation()
const url=el.href
if(!url)return
pjax._loadPage(url,loadjs).then(()=>history.pushState(null,document.title,url))
}
pjax._on.popstate=()=>()=>pjax._loadPage(location.href)
pjax._cbs={}
pjax.on=(evt,cb)=>{
if(!(evt in pjax._cbs)){
pjax._cbs[evt]=[]
}
pjax._cbs[evt].push(cb)
}
pjax.off=(evt,cb)=>{
if(!(evt in pjax._cbs)){
return
}
pjax._cbs[evt]=pjax._cbs[evt].filter(fn=>fn!==cb)
}
pjax.trigger=(evt,...args)=>{
if(!(evt in pjax._cbs)){
return
}
pjax._cbs[evt].forEach(cb=>cb(...args))
}
pjax.start=({match,loadjs=true})=>{
const fn1=pjax._on.click({match,loadjs}),fn2=pjax._on.popstate()
document.addEventListener('click',fn1)
window.addEventListener('popstate',fn2)
const stopbak=pjax.stop
pjax.stop=()=>{
document.removeEventListener('click',fn1)
window.removeEventListener('popstate',fn2)
pjax.stop=stopbak
}
}
pjax.stop=()=>{
throw new Error('pjax hasn\'t started')
}
global.pjax=pjax
})(window)
// ==UserScript==
// @name theme-next-pjax-test
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @require https://cdn.rawgit.com/maple3142/d9c752cebfdd92a7edd1e59ea2cd2f6a/raw/706596f7366660e2d44dd88b7e777d10d20862ad/pjax.js
// @match https://almostover.ru/*
// @match https://rainylog.com/*
// @match http://notes.iissnan.com/*
// @grant none
// ==/UserScript==
;(function() {
'use strict'
pjax.start({
match: el=>el.href&&!/^(#|javascript)/.test(el.getAttribute('href'))&&!/xml$/.test(el.getAttribute('href'))&&el.target!=='_blank'
})
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment