diff --git a/reblocks.asd b/reblocks.asd index b6e9f26a..6836d50b 100644 --- a/reblocks.asd +++ b/reblocks.asd @@ -25,6 +25,7 @@ "reblocks/debug" "reblocks/default-init" "reblocks/commands-hook" + "reblocks/commands-history" "reblocks/widgets/string-widget" "reblocks/widgets/funcall-widget" "reblocks/welcome/widget" diff --git a/src/commands-history.lisp b/src/commands-history.lisp new file mode 100644 index 00000000..a9672d54 --- /dev/null +++ b/src/commands-history.lisp @@ -0,0 +1,40 @@ +(defpackage #:reblocks/commands/history + (:use #:cl) + (:import-from #:reblocks/actions + #:make-action) + (:import-from #:reblocks/commands + #:add-command) + (:export #:browser-history-push-state + #:browser-history-back + #:browser-history-forward)) + +(in-package :reblocks/commands/history) + +(defun browser-history-push-state (url &key (state "{}") + pop-action) + "Invoke history.pushState on the client. + +See: https://developer.mozilla.org/en-US/docs/Web/API/History_API" + (let ((action-code (when pop-action + (etypecase pop-action + (string pop-action) + (function (reblocks/actions:make-action pop-action)))))) + (add-command :update-history + :operation "pushState" + :state state + :url url + :pop-action-code action-code))) + +(defun browser-history-forward () + "Invoke history.forward() on the client. + +See: https://developer.mozilla.org/en-US/docs/Web/API/History_API" + (add-command :update-history + :operation "forward")) + +(defun browser-history-back () + "Invoke history.back() on the client. + +See: https://developer.mozilla.org/en-US/docs/Web/API/History_API" + (add-command :update-history + :operation "back")) diff --git a/src/commands.lisp b/src/commands.lisp index f99f5be2..e8cb43c0 100644 --- a/src/commands.lisp +++ b/src/commands.lisp @@ -6,8 +6,8 @@ #:get-collected-commands #:with-collected-commands #:add-commands)) -(in-package #:reblocks/commands) +(in-package #:reblocks/commands) (defvar *commands*) diff --git a/src/js/jquery/jquery.js b/src/js/jquery/jquery.js index 5645371c..3e2a401e 100644 --- a/src/js/jquery/jquery.js +++ b/src/js/jquery/jquery.js @@ -238,8 +238,39 @@ window.commandHandlers = { 'includeJS': function(params) { include_dom(params.url); }, + 'updateHistory' : function(params) { + switch(params.operation) { + case 'pushState': + let historyState = { + //location: document.location, + state: JSON.parse(params.state), + popActionCode: params.popActionCode + }; + history.pushState(historyState, '', params.url); + break; + case 'back': + history.back(); + break; + case 'forward': + history.forward(); + break; + } + } }; +window.addEventListener("popstate", (event) => { + let historyState = event.state; + console.log(historyState); + if (historyState?.popActionCode) { + initiateAction(historyState.popActionCode, { + args: { + location: document.location, + state: JSON.stringify(historyState.state) + } + }); + } +}); + function processCommand(command) { var method = command.method; // TODO: add a documentation on defining a command handler