|
from org.transcrypt.stubs.browser import __pragma__ |
|
|
|
from illico.common.vendor import Events |
|
|
|
|
|
__pragma__ ('kwargs') |
|
|
|
|
|
|
|
class NavigationManager: |
|
def __init__(self): |
|
self.loaded = False |
|
|
|
def start(self, context=None): |
|
window.console.log("NavigationManager starting.") |
|
|
|
self.context = context |
|
|
|
request = context.request.get(window.location) |
|
request.then(self.inject) |
|
|
|
def bindEvents(self, context=None): |
|
e = Events(window) |
|
e.on('popstate', self.popstate) |
|
|
|
e = Events(document) |
|
e.on('click', 'a', self.navigate) |
|
|
|
def popstate(self, e): |
|
if not e.state: |
|
return |
|
|
|
window.console.debug("Attempting to move through time.", e.state, e) |
|
|
|
def navigate(self, e): |
|
if not e.target.href.startswith(window.location.protocol + '//' + window.location.host + '/'): |
|
return |
|
|
|
# TODO: Seek through parents for a <button> or a <a> if we aren't already pointing at one. |
|
|
|
if e.target.classList.contains('no-nav'): |
|
return |
|
|
|
window.console.debug("Attempting navigation.", e.target.href, e) |
|
target = document.getElementsByTagName('main')[0] |
|
|
|
for i in range(1, target.children.length): |
|
target.children[1].remove() |
|
|
|
target.classList.add('loading') |
|
|
|
request = self.context.request.get(window.location) |
|
request.then(self.inject) |
|
|
|
return False |
|
|
|
def inject(self, error, text, xhr): |
|
if error: |
|
window.console.error("Unable to load main content.", xhr.status, xhr.statusText, xhr) |
|
return |
|
|
|
window.console.debug("Loaded content.", xhr) |
|
self._inject(text, xhr.responseURL) |
|
|
|
def _inject(self, text, responseURL): |
|
parser = new(DOMParser) |
|
element = parser.parseFromString(text, "text/html") |
|
target = document.getElementsByTagName('main')[0] |
|
|
|
while element.body.children.length: |
|
target.appendChild(element.body.children[0]) |
|
|
|
target.classList.remove('loading') |
|
|
|
header = document.getElementsByTagName('h3') |
|
|
|
if header.length: |
|
title = header[0].textContent.strip() |
|
state = {'title': title, 'url': responseURL} |
|
title += ' – Illico Hodes RITA' |
|
|
|
document.title = title |
|
|
|
if not history.state: |
|
# First page load won't have any state. |
|
window.console.debug("Setting initial state.", state) |
|
history.replaceState(state, title, responseURL) |
|
|
|
elif history.state.url != window.location: |
|
# Refreshing and re-navigation to the same target should avoid pushing duplicate state. |
|
window.console.debug("Pushing new state.", state) |
|
history.pushState(state, title, responseURL) |
This is good stuff.