Skip to content

Commit

Permalink
Add support for push state
Browse files Browse the repository at this point in the history
  • Loading branch information
edelvalle committed Jun 20, 2019
1 parent 49396d4 commit 27f5851
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 4 deletions.
4 changes: 4 additions & 0 deletions reactor/channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,7 @@ def remove(self, event):
def redirect(self, event):
log.debug(f"<<< REDIRECT {event['url']}")
self.send_json(dict(event, type='redirect'))

def push_state(self, event):
log.debug(f"<<< PUSH-STATE {event['url']}")
self.send_json(dict(event, type='push_state'))
14 changes: 11 additions & 3 deletions reactor/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ def build(cls, tag_name, *args, **kwargs):
def __init__(self, context, id=None):
self._context = context
self._destroy_sent = False
self._redirect_sent = False
self._redirected_to = None
self._last_sent_html = ''
self._diff = diff_match_patch()
Expand Down Expand Up @@ -152,10 +153,15 @@ def send_destroy(self):
id=self.id,
)

def send_redirect(self, url):
def send_redirect(self, url, push_state=True):
url = reverse(url)
if self._channel_name:
send_to_channel(self._channel_name, 'redirect', url=url)
if push_state:
action = 'push_state'
else:
action = 'redirect'
send_to_channel(self._channel_name, action, url=url)
self._redirect_sent = True
else:
self._redirected_to = url

Expand Down Expand Up @@ -184,7 +190,9 @@ def render_diff(self):
]

def render(self):
if self._destroy_sent:
if self._redirect_sent:
html = self._last_sent_html
elif self._destroy_sent:
html = ''
elif self._redirected_to:
html = (
Expand Down
29 changes: 28 additions & 1 deletion reactor/static/reactor.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ reactor_channel.on 'close', ->
reactor_channel.on 'message', ({type, id, html_diff, url}) ->
console.log '<<<', type.toUpperCase(), id or url
if type is 'redirect'
location.assign url
window.location.assign url
else if type is 'push_state'
push_state url
else
el = document.getElementById(id)
if el?
Expand Down Expand Up @@ -241,4 +243,29 @@ debounce = (delay_name, delay) -> (...args) ->
clearTimeout _timeouts[delay_name]
_timeouts[delay_name] = setTimeout (=> send(...args)), delay

push_state = (url) ->
if history.pushState?
history.pushState {}, '', url
load_page url
else
window.location.assign url

window.onpopstate = ->
load_page window.location.href

load_page = (url) ->
utf8_decoder = new TextDecoder("utf-8")
fetch(url).then (response) ->
reader = await response.body.getReader()
done = false
result = []
while not done
{done, value} = await reader.read()
value = if value then utf8_decoder.decode(value) else ''
result.push value
html = result.join('').trim()
window.requestAnimationFrame ->
morphdom(document.documentElement, html)
document.querySelector('[autofocus]')?.focus()

reactor_channel.open()

0 comments on commit 27f5851

Please sign in to comment.