mirror of
https://github.com/rabbibotton/clog.git
synced 2026-01-01 14:52:01 -08:00
Client side storage
This commit is contained in:
parent
f5cf78500a
commit
c1c08db9b3
7 changed files with 129 additions and 10 deletions
|
|
@ -138,6 +138,7 @@ Tutorial Summary
|
|||
- 11-tutorial.lisp - Attaching to existing HTML
|
||||
- 12-tutorial.lisp - Running a website in CLOG (routing)
|
||||
- 13-tutorial/ - Flying Solo - A minimalist CLOG project
|
||||
- 14-tutorial.lisp - Local (persistent) and Session client side storage
|
||||
|
||||
Demo Summary
|
||||
|
||||
|
|
|
|||
|
|
@ -174,10 +174,10 @@
|
|||
;; reload ;;
|
||||
;;;;;;;;;;;;
|
||||
|
||||
(defgeneric reload (clog-window)
|
||||
(defgeneric reload (clog-location)
|
||||
(:documentation "Reload browser window."))
|
||||
|
||||
(defmethod reload ((obj clog-window))
|
||||
(defmethod reload ((obj clog-location))
|
||||
(execute obj "reload()"))
|
||||
|
||||
;;;;;;;;;;;;;;;;;
|
||||
|
|
|
|||
|
|
@ -468,8 +468,6 @@ If ON-ORIENTATION-CHANGE-HANDLER is nil unbind the event."))
|
|||
;; set-on-storage ;;
|
||||
;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; need to change to use a true on-storage event
|
||||
|
||||
(defparameter storage-event-script
|
||||
"+ encodeURIComponent(e.originalEvent.key) + ':' +
|
||||
encodeURIComponent(e.originalEvent.oldValue) + ':' +
|
||||
|
|
@ -478,13 +476,13 @@ If ON-ORIENTATION-CHANGE-HANDLER is nil unbind the event."))
|
|||
(defun parse-storage-event (data)
|
||||
(let ((f (ppcre:split ":" data)))
|
||||
(list
|
||||
:key-value (quri:url-decode (nth 0 f))
|
||||
:key (quri:url-decode (nth 0 f))
|
||||
:old-value (quri:url-decode (nth 1 f))
|
||||
:new-value (quri:url-decode (nth 2 f)))))
|
||||
:value (quri:url-decode (nth 2 f)))))
|
||||
|
||||
(defgeneric set-on-storage (clog-window on-storage-handler)
|
||||
(:documentation "Set the ON-STORAGE-HANDLER for CLOG-OBJ. If
|
||||
ON-STORAGE-HANDLER is nil unbind the event."))
|
||||
(:documentation "Set the ON-STORAGE-HANDLER for CLOG-OBJ. The
|
||||
on-storage event is fired for changes to :local storage keys."))
|
||||
|
||||
(defmethod set-on-storage ((obj clog-window) handler)
|
||||
(set-event obj "storage"
|
||||
|
|
@ -492,3 +490,60 @@ ON-STORAGE-HANDLER is nil unbind the event."))
|
|||
(lambda (data)
|
||||
(funcall handler obj (parse-storage-event data))))
|
||||
:call-back-script storage-event-script))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;
|
||||
;; storage-length ;;
|
||||
;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(deftype storage-type '(member local session))
|
||||
|
||||
(defgeneric storage-length (clog-window storage-type)
|
||||
(:documentation "Number of entries in browser STORAGE-TYPE.
|
||||
(local = persistant or session)"))
|
||||
|
||||
(defmethod storage-length ((obj clog-window) storage-type)
|
||||
(parse-integer (query obj "~(~a~)Storage.length" storage-type)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;
|
||||
;; storage-key ;;
|
||||
;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defgeneric storage-key (clog-window storage-type key-num)
|
||||
(:documentation "Return the key for entry number KEY-NUM in browser
|
||||
STORAGE-TYPE. (local = persistant or session)"))
|
||||
|
||||
(defmethod storage-key ((obj clog-window) storage-type key-num)
|
||||
(query obj (format nil "~(~a~)Storage.key(~A)" storage-type key-num)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;
|
||||
;; storage-remove ;;
|
||||
;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defgeneric storage-remove (clog-window storage-type key-name)
|
||||
(:documentation "Remove the storage key and value in browser
|
||||
STORAGE-TYPE. (local = persistant or session)"))
|
||||
|
||||
(defmethod storage-remove ((obj clog-window) storage-type key-name)
|
||||
(execute obj (format nil "~(~a~)Storage.removeItem(~A)" storage-type key-name)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;
|
||||
;; storage-element ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defgeneric storage-element (clog-window storage-type key-name)
|
||||
(:documentation "Get/Setf storage-element on browser client."))
|
||||
|
||||
(defmethod storage-element ((obj clog-window) storage-type key-name)
|
||||
(query obj (format nil "~(~a~)Storage.getItem('~A')"
|
||||
storage-type
|
||||
(escape-string key-name))))
|
||||
|
||||
(defgeneric set-storage-element (clog-window storage-type key-name value)
|
||||
(:documentation "Set storage-element."))
|
||||
|
||||
(defmethod set-storage-element ((obj clog-window) storage-type key-name value)
|
||||
(execute obj (format nil "~(~a~)Storage.setItem('~A','~A')"
|
||||
storage-type
|
||||
(escape-string key-name)
|
||||
(escape-string value))))
|
||||
(defsetf storage-element set-storage-element)
|
||||
|
|
|
|||
2
clog.asd
2
clog.asd
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
:author "David Botton <david@botton.com>"
|
||||
:license "BSD"
|
||||
:version "0.1.1"
|
||||
:version "0.2.0"
|
||||
:serial t
|
||||
:depends-on (#:clack #:websocket-driver #:alexandria #:hunchentoot #:cl-ppcre
|
||||
#:bordeaux-threads #:trivial-open-browser
|
||||
|
|
|
|||
|
|
@ -471,6 +471,10 @@ embedded in a native template application.)"
|
|||
(scroll-to generic-function)
|
||||
(close-window generic-function)
|
||||
(close-connection generic-function)
|
||||
(storage-length generic-function)
|
||||
(storage-key generic-function)
|
||||
(storage-remove generic-function)
|
||||
(storage-element generic-function)
|
||||
|
||||
"CLOG-Window - Events"
|
||||
(set-on-abort generic-function)
|
||||
|
|
@ -537,6 +541,7 @@ embedded in a native template application.)"
|
|||
(export 'make-markup)
|
||||
(defun make-markup ()
|
||||
(load "clog.lisp")
|
||||
(load "clog-docs.lisp")
|
||||
(load "clog-base.lisp")
|
||||
(load "clog-element.lisp")
|
||||
(load "clog-element-common.lisp")
|
||||
|
|
@ -554,6 +559,7 @@ embedded in a native template application.)"
|
|||
(export 'make-html)
|
||||
(defun make-html ()
|
||||
(load "clog.lisp")
|
||||
(load "clog-docs.lisp")
|
||||
(load "clog-base.lisp")
|
||||
(load "clog-element.lisp")
|
||||
(load "clog-element-common.lisp")
|
||||
|
|
|
|||
56
tutorial/14-tutorial.lisp
Normal file
56
tutorial/14-tutorial.lisp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
(defpackage #:clog-user
|
||||
(:use #:cl #:clog)
|
||||
(:export start-tutorial))
|
||||
|
||||
(in-package :clog-user)
|
||||
|
||||
(defun on-new-window (body)
|
||||
(set-on-click (create-button body :content "Set Local Key")
|
||||
(lambda (obj)
|
||||
(setf (storage-element (window body) :local "my-local-key")
|
||||
(get-universal-time))
|
||||
(reload (location body))))
|
||||
|
||||
(set-on-click (create-button body :content "Set Session Key")
|
||||
(lambda (obj)
|
||||
(setf (storage-element (window body) :session "my-session-key")
|
||||
(get-universal-time))
|
||||
(reload (location body))))
|
||||
|
||||
(set-on-storage (window body)
|
||||
(lambda (obj data)
|
||||
(create-div body :content
|
||||
(format nil "<br>~A : ~A => ~A<br>"
|
||||
(getf data ':key)
|
||||
(getf data ':old-value)
|
||||
(getf data ':value)))))
|
||||
|
||||
|
||||
(create-div body :content (format nil
|
||||
"<H1>Local Storage vs Session Storage</H1>
|
||||
<p width=500>
|
||||
The value of local storage persists in browser cache even after browser closed.
|
||||
If you reset this page the session storage key will remain the same, but openning
|
||||
in another window or tab will be a new session but if came from a click from this
|
||||
window the session keys are copied first to the new window.</p>
|
||||
<br>
|
||||
<a href='.' target='_blank'>Another Window = Different Session</a><br>
|
||||
<br>
|
||||
<br>
|
||||
Local Storage key: ~A := ~A<br>
|
||||
<br>
|
||||
Session Storage key: ~A := ~A<br>
|
||||
<br>
|
||||
Changes made to a local key will fire an event and print below:<br>"
|
||||
"my-local-key"
|
||||
(storage-element (window body) :local "my-local-key")
|
||||
"my-session-key"
|
||||
(storage-element (window body) :session "my-session-key")))
|
||||
|
||||
(run body))
|
||||
|
||||
(defun start-tutorial ()
|
||||
"Start turtorial."
|
||||
|
||||
(initialize #'on-new-window)
|
||||
(open-browser))
|
||||
|
|
@ -46,3 +46,4 @@ Tutorial Summary
|
|||
- 11-tutorial.lisp - Attaching to existing HTML
|
||||
- 12-tutorial.lisp - Running a website in CLOG (routing)
|
||||
- 13-tutorial/ - Flying Solo - A minimalist CLOG project
|
||||
- 14-tutorial.lisp - Local (persistent) and Session client side storage
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue