mirror of
https://github.com/openvk/openvk
synced 2024-12-23 00:51:03 +03:00
Simple ajax routing (scripts are broken)
This commit is contained in:
parent
f690ff7df7
commit
1cf9ed0c8e
11 changed files with 289 additions and 9 deletions
|
@ -283,10 +283,11 @@ abstract class OpenVKPresenter extends SimplePresenter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if($this->queryParam('al') == '1') {
|
if($this->queryParam('al') == '1') {
|
||||||
|
error_reporting(0);
|
||||||
$this->assertNoCSRF();
|
$this->assertNoCSRF();
|
||||||
header('Content-Type: text/plain; charset=UTF-8');
|
header('Content-Type: text/plain; charset=UTF-8');
|
||||||
}*/
|
}
|
||||||
|
|
||||||
parent::onStartup();
|
parent::onStartup();
|
||||||
}
|
}
|
||||||
|
|
|
@ -446,6 +446,7 @@
|
||||||
{ifset bodyScripts}
|
{ifset bodyScripts}
|
||||||
{include bodyScripts}
|
{include bodyScripts}
|
||||||
{/ifset}
|
{/ifset}
|
||||||
|
{script "js/router.js"}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -242,7 +242,7 @@
|
||||||
if(response.success) {
|
if(response.success) {
|
||||||
u("#backToUpload").trigger("click")
|
u("#backToUpload").trigger("click")
|
||||||
NewNotification(tr("success"), tr("audio_successfully_uploaded"), null, () => {
|
NewNotification(tr("success"), tr("audio_successfully_uploaded"), null, () => {
|
||||||
window.location.assign(response.redirect_link)
|
window.router.route(response.redirect_link)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
fastError(response.flash.message)
|
fastError(response.flash.message)
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
let link = "/gifts?act=confirm&user={$user->getId()}&pack={$cat->getId()}&elid=";
|
let link = "/gifts?act=confirm&user={$user->getId()}&pack={$cat->getId()}&elid=";
|
||||||
let gift = el.data("gift");
|
let gift = el.data("gift");
|
||||||
|
|
||||||
window.location.assign(link + gift);
|
window.router.route(link + gift);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{/block}
|
{/block}
|
|
@ -2831,6 +2831,10 @@ a.poll-retract-vote {
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.page_header.search_expanded_at_all .header_navigation #search_box #searchBoxFastTips.shown {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.page_header.search_expanded .link {
|
.page_header.search_expanded .link {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,7 +157,7 @@ u(document).on('click', '#__feed_settings_link', (e) => {
|
||||||
FINAL_URL.searchParams.delete('return_banned')
|
FINAL_URL.searchParams.delete('return_banned')
|
||||||
}
|
}
|
||||||
|
|
||||||
window.location.assign(FINAL_URL.href)
|
window.router.route(FINAL_URL.href)
|
||||||
})
|
})
|
||||||
|
|
||||||
COUNT.forEach(item => {
|
COUNT.forEach(item => {
|
||||||
|
|
|
@ -664,7 +664,7 @@ u(document).on('keyup', (e) => {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!window.player) {
|
if(!window.player || !window.player.isAtAudiosPage()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1294,7 +1294,7 @@ $(document).on("click", "#_deletePlaylist", (e) => {
|
||||||
},
|
},
|
||||||
success: (response) => {
|
success: (response) => {
|
||||||
if(response.success) {
|
if(response.success) {
|
||||||
window.location.assign("/playlists" + response.id)
|
window.router.route("/playlists" + response.id)
|
||||||
} else {
|
} else {
|
||||||
fastError(response.flash.message)
|
fastError(response.flash.message)
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ $(document).on("click", "#endUploading", (e) => {
|
||||||
document.querySelector(".page_content .insertPhotos").innerHTML = ""
|
document.querySelector(".page_content .insertPhotos").innerHTML = ""
|
||||||
document.getElementById("endUploading").style.display = "none"
|
document.getElementById("endUploading").style.display = "none"
|
||||||
|
|
||||||
NewNotification(tr("photos_successfully_uploaded"), tr("click_to_go_to_album"), null, () => {window.location.assign(`/album${result.owner}_${result.album}`)})
|
NewNotification(tr("photos_successfully_uploaded"), tr("click_to_go_to_album"), null, () => {window.router.route({url:`/album${result.owner}_${result.album}`})})
|
||||||
|
|
||||||
document.querySelector(".whiteBox").style.display = "block"
|
document.querySelector(".whiteBox").style.display = "block"
|
||||||
document.querySelector(".insertAgain").append(document.getElementById("fakeButton"))
|
document.querySelector(".insertAgain").append(document.getElementById("fakeButton"))
|
||||||
|
|
|
@ -53,8 +53,9 @@ u(document).on('click', '.menu_toggler', (e) => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
$(document).on("click", ".post-like-button", function(e) {
|
u(document).on("click", ".post-like-button", function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
e.stopPropagation()
|
||||||
|
|
||||||
var thisBtn = u(this).first();
|
var thisBtn = u(this).first();
|
||||||
var link = u(this).attr("href");
|
var link = u(this).attr("href");
|
||||||
|
|
239
Web/static/js/router.js
Normal file
239
Web/static/js/router.js
Normal file
|
@ -0,0 +1,239 @@
|
||||||
|
window.router = new class {
|
||||||
|
skeletons = {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
get csrf() {
|
||||||
|
return u("meta[name=csrf]").attr("value")
|
||||||
|
}
|
||||||
|
|
||||||
|
__isScriptAlreadyLoaded(script) {
|
||||||
|
if(script.src) {
|
||||||
|
const script_url = new URL(script.src)
|
||||||
|
const script_main_part = script_url.pathname
|
||||||
|
console.log(script_main_part)
|
||||||
|
return u(`script[src^='${script_main_part}']`).length > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
__appendScript(script) {
|
||||||
|
const _t_scr = document.createElement('script')
|
||||||
|
if(script.src) {
|
||||||
|
_t_scr.src = script.src
|
||||||
|
} else {
|
||||||
|
_t_scr.textContent = script.textContent
|
||||||
|
}
|
||||||
|
|
||||||
|
document.body.appendChild(_t_scr)
|
||||||
|
}
|
||||||
|
|
||||||
|
__clearScripts() {
|
||||||
|
u(`script:not([src])`).remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
__appendPage(parsed_content) {
|
||||||
|
if(u('.paginator:not(.paginator-at-top)').length > 0) {
|
||||||
|
showMoreObserver.unobserve(u('.paginator:not(.paginator-at-top)').nodes[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
const page_body = u(parsed_content.querySelector('.page_body'))
|
||||||
|
const sidebar = u(parsed_content.querySelector('.sidebar'))
|
||||||
|
const page_header = u(parsed_content.querySelector('.page_header'))
|
||||||
|
|
||||||
|
if(page_body.length < 1) {
|
||||||
|
makeError('Err')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.__clearScripts()
|
||||||
|
parsed_content.querySelectorAll('script').forEach(script => {
|
||||||
|
console.log(script)
|
||||||
|
if(!this.__isScriptAlreadyLoaded(script)) {
|
||||||
|
this.__appendScript(script)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
u('.page_body').html(page_body.html())
|
||||||
|
u('.sidebar').html(sidebar.html())
|
||||||
|
if(u('.page_header #search_box select').length > 0 && page_header.find('#search_box select').length > 0) {
|
||||||
|
u('.page_header #search_box select').nodes[0].value = page_header.find('#search_box select').nodes[0].value
|
||||||
|
}
|
||||||
|
|
||||||
|
if(page_header.hasClass('search_expanded_at_all')) {
|
||||||
|
u('.page_header').addClass('search_expanded_at_all').addClass('search_expanded')
|
||||||
|
} else {
|
||||||
|
if(u('.page_header').hasClass('search_expanded_at_all')) {
|
||||||
|
u('.page_header').removeClass('search_expanded_at_all').removeClass('search_expanded')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u("meta[name=csrf]").attr("value", u(parsed_content.querySelector('meta[name=csrf]')).attr('value'))
|
||||||
|
|
||||||
|
document.title = parsed_content.title
|
||||||
|
window.scrollTo(0, 0)
|
||||||
|
bsdnHydrate()
|
||||||
|
|
||||||
|
if(u('.paginator:not(.paginator-at-top)').length > 0) {
|
||||||
|
showMoreObserver.observe(u('.paginator:not(.paginator-at-top)').nodes[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkUrl(url) {
|
||||||
|
if((localStorage.getItem('ux.disable_ajax_routing') ?? 0) == 1 || window.openvk.current_id == 0) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!url || url == '') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if(url.indexOf(location.origin) == -1) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
async route(params = {}) {
|
||||||
|
if(typeof params == 'string') {
|
||||||
|
params = {
|
||||||
|
url: params
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const old_url = location.href
|
||||||
|
let url = params.url
|
||||||
|
if(url.indexOf(location.origin)) {
|
||||||
|
url = location.origin + url
|
||||||
|
}
|
||||||
|
|
||||||
|
if((localStorage.getItem('ux.disable_ajax_routing') ?? 0) == 1 || window.openvk.current_id == 0) {
|
||||||
|
window.location.assign(url)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const push_url = params.push_state ?? true
|
||||||
|
const next_page_url = new URL(url)
|
||||||
|
next_page_url.searchParams.append('al', 1)
|
||||||
|
next_page_url.searchParams.append('hash', this.csrf)
|
||||||
|
if(push_url) {
|
||||||
|
history.pushState({'from_router': 1}, '', url)
|
||||||
|
} else {
|
||||||
|
history.replaceState({'from_router': 1}, '', url)
|
||||||
|
}
|
||||||
|
|
||||||
|
const parser = new DOMParser
|
||||||
|
const next_page_request = await fetch(next_page_url, {
|
||||||
|
method: 'GET'
|
||||||
|
})
|
||||||
|
const next_page_text = await next_page_request.text()
|
||||||
|
const parsed_content = parser.parseFromString(next_page_text, 'text/html')
|
||||||
|
if(next_page_request.redirected) {
|
||||||
|
history.replaceState({'from_router': 1}, '', next_page_request.url)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.__appendPage(parsed_content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u(document).on('click', 'a', async (e) => {
|
||||||
|
const target = u(e.target).closest('a')
|
||||||
|
const dom_url = target.attr('href')
|
||||||
|
const id = target.attr('id')
|
||||||
|
let url = target.nodes[0].href
|
||||||
|
|
||||||
|
if(id) {
|
||||||
|
if(['act_tab_a', 'ki'].indexOf(id) == -1) {
|
||||||
|
console.log('AJAX | Skipping cuz maybe its function call link.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!dom_url || dom_url == '#' || dom_url.indexOf('javascript:') != -1) {
|
||||||
|
console.log('AJAX | Skipped cuz its anchor or function call')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if(target.attr('target') == '_blank') {
|
||||||
|
console.log('AJAX | Skipping cuz its _blank.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!window.router.checkUrl(url)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
console.log(`AJAX | Going to URL ${url}`)
|
||||||
|
await window.router.route({
|
||||||
|
url: url,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
u(document).on('submit', 'form', async (e) => {
|
||||||
|
if(u('#ajloader').hasClass('shown')) {
|
||||||
|
e.preventDefault()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if((localStorage.getItem('ux.disable_ajax_routing') ?? 0) == 1 || window.openvk.current_id == 0) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
e.preventDefault()
|
||||||
|
u('#ajloader').addClass('shown')
|
||||||
|
|
||||||
|
const form = e.target
|
||||||
|
const method = form.method ?? 'get'
|
||||||
|
const url = form.action
|
||||||
|
|
||||||
|
const url_object = new URL(url)
|
||||||
|
url_object.searchParams.append('al', 1)
|
||||||
|
if(method == 'get' || method == 'GET') {
|
||||||
|
url_object.searchParams.append('hash', window.router.csrf)
|
||||||
|
$(form).serializeArray().forEach(param => {
|
||||||
|
url_object.searchParams.append(param.name, param.value)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!url) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const form_data = serializeForm(form)
|
||||||
|
const request_object = {
|
||||||
|
method: method
|
||||||
|
}
|
||||||
|
|
||||||
|
if(method != 'GET' && method != 'get') {
|
||||||
|
request_object.body = form_data
|
||||||
|
}
|
||||||
|
|
||||||
|
const form_res = await fetch(url_object, request_object)
|
||||||
|
const form_result = await form_res.text()
|
||||||
|
switch(form_res.status) {
|
||||||
|
case 500:
|
||||||
|
makeError(form_res.statusText)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
const parser = new DOMParser
|
||||||
|
const parsed_content = parser.parseFromString(form_result, 'text/html')
|
||||||
|
|
||||||
|
if(form_res.redirected) {
|
||||||
|
history.replaceState({'from_router': 1}, '', form_res.url)
|
||||||
|
} else {
|
||||||
|
const __new_url = new URL(form_res.url)
|
||||||
|
__new_url.searchParams.delete('al')
|
||||||
|
__new_url.searchParams.delete('hash')
|
||||||
|
|
||||||
|
history.pushState({'from_router': 1}, '', __new_url)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(form_res)
|
||||||
|
window.router.__appendPage(parsed_content)
|
||||||
|
|
||||||
|
u('#ajloader').removeClass('shown')
|
||||||
|
})
|
|
@ -181,3 +181,37 @@ function getRemainingTime(fullTime, time) {
|
||||||
|
|
||||||
return "-" + fmtTime(timer)
|
return "-" + fmtTime(timer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function serializeForm(form)
|
||||||
|
{
|
||||||
|
const u_ = u(form)
|
||||||
|
const inputs = u_.find('input, textarea')
|
||||||
|
console.log(inputs)
|
||||||
|
let fd = new FormData()
|
||||||
|
inputs.nodes.forEach(inp => {
|
||||||
|
if(!inp || !inp.name) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if(inp.type == 'submit') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(inp.type) {
|
||||||
|
case 'submit':
|
||||||
|
return
|
||||||
|
case 'hidden':
|
||||||
|
case 'text':
|
||||||
|
case 'textarea':
|
||||||
|
fd.append(inp.name, inp.value)
|
||||||
|
break
|
||||||
|
case 'file':
|
||||||
|
for(const __file of inp.files) {
|
||||||
|
fd.append(inp.name, __file)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return fd
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue