diff --git a/clog-base.lisp b/clog-base.lisp
index a2df57e..83e48d4 100644
--- a/clog-base.lisp
+++ b/clog-base.lisp
@@ -84,6 +84,30 @@ result. (Private)"))
(cc:query (connection-id obj)
(format nil "~A.~A" (jquery obj) method)))
+;;;;;;;;;;;;;
+;; execute ;;
+;;;;;;;;;;;;;
+
+(defgeneric execute (clog-obj method)
+ (:documentation "Execute the js METHOD on OBJ. Result is
+dicarded. (Private)"))
+
+(defmethod execute ((obj clog-obj) method)
+ (cc:execute (connection-id obj)
+ (format nil "~A.~A" (script-id obj) method)))
+
+;;;;;;;;;;;
+;; query ;;
+;;;;;;;;;;;
+
+(defgeneric query (clog-obj method)
+ (:documentation "Execute the js query METHOD on OBJ and return
+result. (Private)"))
+
+(defmethod query ((obj clog-obj) method)
+ (cc:query (connection-id obj)
+ (format nil "~A.~A" (script-id obj) method)))
+
;;;;;;;;;;;;;;;;;;;;;;;
;; bind-event-script ;;
;;;;;;;;;;;;;;;;;;;;;;;
@@ -142,8 +166,8 @@ result. (Private)"))
;;;;;;;;;;;;;;;;;;;;;;;;;;
(defparameter keyboard-event-script
- "+ e.keyCode + ':' + e.charCode + ':' + e.altKey + ':' + e.ctrlKey + ':'
- + e.shiftKey + ':' + e.metaKey")
+ "+ e.keyCode + ':' + e.charCode + ':' + e.altKey + ':' + e.ctrlKey + ':' +
+ e.shiftKey + ':' + e.metaKey")
(defun parse-keyboard-event (data)
(let ((f (ppcre:split ":" data)))
@@ -187,7 +211,7 @@ result. (Private)"))
(:documentation "Set html property."))
(defmethod set-property ((obj clog-obj) property-name value)
- (jquery-execute obj (format nil "prop('~A','~A')" property-name value)))
+ (jquery-execute obj (format nil "prop('~A','~A')" property-name (escape-string value))))
(defsetf property set-property)
;;;;;;;;;;;
@@ -204,7 +228,7 @@ result. (Private)"))
(:documentation "Set css style."))
(defmethod set-style ((obj clog-obj) style-name value)
- (jquery-execute obj (format nil "css('~A','~A')" style-name value)))
+ (jquery-execute obj (format nil "css('~A','~A')" style-name (escape-string value))))
(defsetf style set-style)
;;;;;;;;;;;;;;;
@@ -221,7 +245,7 @@ result. (Private)"))
(:documentation "Set html tag attribute."))
(defmethod set-attribute ((obj clog-obj) attribute-name value)
- (jquery-execute obj (format nil "attr('~A','~A')" attribute-name value)))
+ (jquery-execute obj (format nil "attr('~A','~A')" attribute-name (escape-string value))))
(defsetf attribute set-attribute)
;;;;;;;;;;;;
diff --git a/clog-body.lisp b/clog-body.lisp
index bc266cd..22416df 100644
--- a/clog-body.lisp
+++ b/clog-body.lisp
@@ -17,9 +17,9 @@
((window
:reader window
:initarg :window)
- (document
+ (html-document
:reader html-document
- :initarg :document)
+ :initarg :html-document)
(location
:reader location
:initarg :location)
@@ -37,10 +37,10 @@
(make-instance
'clog-body
:connection-id connection-id :html-id 0
- :window (make-instance 'clog-window :connection-id connection-id)
- :window (make-instance 'clog-document :connection-id connection-id)
- :window (make-instance 'clog-location :connection-id connection-id)
- :window (make-instance 'clog-navigator :connection-id connection-id)))
+ :window (make-clog-window connection-id)
+ :html-document (make-clog-document connection-id)
+ :location (make-clog-location connection-id)
+ :navigator (make-clog-navigator connection-id)))
;;;;;;;;;;;;
;; window ;;
diff --git a/clog-document.lisp b/clog-document.lisp
index 2736e76..64481fe 100644
--- a/clog-document.lisp
+++ b/clog-document.lisp
@@ -23,3 +23,161 @@
(defun make-clog-document (connection-id)
"Construct a new clog-document. (Private)"
(make-instance 'clog-document :connection-id connection-id :html-id "document"))
+
+;;;;;;;;;;;;
+;; domain ;;
+;;;;;;;;;;;;
+
+(defgeneric domain (clog-document)
+ (:documentation "Get domain."))
+
+(defmethod domain ((obj clog-document))
+ (query obj "domain"))
+
+;;;;;;;;;;;;;;;;;;;;
+;; input-encoding ;;
+;;;;;;;;;;;;;;;;;;;;
+
+(defgeneric input-encoding (clog-document)
+ (:documentation "Get input encoding."))
+
+(defmethod input-encoding ((obj clog-document))
+ (query obj "inputEncoding"))
+
+;;;;;;;;;;;;;;;;;;;
+;; last-modified ;;
+;;;;;;;;;;;;;;;;;;;
+
+(defgeneric last-modified (clog-document)
+ (:documentation "Get last modified."))
+
+(defmethod last-modified ((obj clog-document))
+ (query obj "lastModified"))
+
+;;;;;;;;;;;;;
+;; referer ;;
+;;;;;;;;;;;;;
+
+(defgeneric referer (clog-document)
+ (:documentation "Get referer."))
+
+(defmethod referer ((obj clog-document))
+ (query obj "referer"))
+
+;;;;;;;;;;;
+;; title ;;
+;;;;;;;;;;;
+
+(defgeneric title (clog-document)
+ (:documentation "Get/setf title."))
+
+(defmethod title ((obj clog-document))
+ (query obj "title"))
+
+(defgeneric set-title (clog-document value))
+
+(defmethod set-title ((obj clog-document) value)
+ (execute obj (format nil "title='~A'" (cc:escape-string value))))
+(defsetf title set-title)
+
+;;;;;;;;;
+;; url ;;
+;;;;;;;;;
+
+(defgeneric url (clog-document)
+ (:documentation "Get url."))
+
+(defmethod url ((obj clog-document))
+ (query obj "url"))
+
+;;;;;;;;;;;;;;;;;;;;;;
+;; document-element ;;
+;;;;;;;;;;;;;;;;;;;;;;
+
+(defgeneric document-element (clog-document)
+ (:documentation "Get document-element."))
+
+(defmethod document-element ((obj clog-document))
+ (make-instance 'clog-base :connection-id (connection-id obj) :html-id "documentElement"))
+
+;;;;;;;;;;;;;;;;;;
+;; head-element ;;
+;;;;;;;;;;;;;;;;;;
+
+(defgeneric head-element (clog-document)
+ (:documentation "Get head-element."))
+
+(defmethod head-element ((obj clog-document))
+ (make-instance 'clog-base :connection-id (connection-id obj) :html-id "head"))
+
+;;;;;;;;;;
+;; body ;;
+;;;;;;;;;;
+
+(defgeneric body-element (clog-document)
+ (:documentation "Get body-element."))
+
+(defmethod body-element ((obj clog-document))
+ (make-instance 'clog-base :connection-id (connection-id obj) :html-id "body"))
+
+;;;;;;;;;;;;;;;;;
+;; ready-state ;;
+;;;;;;;;;;;;;;;;;
+
+(defgeneric ready-state (clog-document)
+ (:documentation "Get ready-state."))
+
+(defmethod ready-state ((obj clog-document))
+ (query obj "readyState"))
+
+;;;;;;;;;;;;;;
+;; load-css ;;
+;;;;;;;;;;;;;;
+
+(defgeneric load-css (clog-document css-url)
+ (:documentation "Load css from CSS-URL."))
+
+(defmethod load-css ((obj clog-document) css-url)
+ (jquery-execute (head-element obj)
+ (format nil "append('')" (escape-string css-url))))
+
+;;;;;;;;;
+;; put ;;
+;;;;;;;;;
+
+(defgeneric put (clog-document message)
+ (:documentation "Write text to browser document object."))
+
+(defmethod put ((obj clog-document) message)
+ (execute obj (format nil "write('~A')" (escape-string message))))
+
+;;;;;;;;;;;;;;
+;; put-line ;;
+;;;;;;;;;;;;;;
+
+(defgeneric put-line (clog-document message)
+ (:documentation "Write text to browser document object with new-line."))
+
+(defmethod put-line ((obj clog-document) message)
+ (execute obj (format nil "writeln('~A')" (escape-string message))))
+
+;;;;;;;;;;;;
+;; put-br ;;
+;;;;;;;;;;;;
+
+(defgeneric put-br (clog-document message)
+ (:documentation "Write text to browser document object with <\br>new-line."))
+
+(defmethod put-br ((obj clog-document) message)
+ (execute obj (format nil "writeln('~A<\br>')" (escape-string message))))
+
+;;;;;;;;;;;;;;
+;; new-line ;;
+;;;;;;;;;;;;;;
+
+(defgeneric new-line (clog-document)
+ (:documentation "Write to browser document <\br>new-line."))
+
+(defmethod new-line ((obj clog-document))
+ (execute obj (format nil "writeln('<\br>')")))
diff --git a/clog-utilities.lisp b/clog-utilities.lisp
index b370385..2a29074 100644
--- a/clog-utilities.lisp
+++ b/clog-utilities.lisp
@@ -28,3 +28,16 @@
(defun open-browser (&key (url "http://127.0.0.1:8080"))
"Open a web browser to URL."
(trivial-open-browser:open-browser url))
+
+;;;;;;;;;;;;;;;;;;;
+;; escape-string ;;
+;;;;;;;;;;;;;;;;;;;
+
+(defun escape-string (str)
+ "Escape STR for sending to browser script."
+ (let ((res))
+ (setf res (ppcre:regex-replace-all "\\x22" str "\\x22"))
+ (setf res (ppcre:regex-replace-all "\\x27" res "\\x27"))
+ (setf res (ppcre:regex-replace-all "\\x0A" res "\\x0A"))
+ (setf res (ppcre:regex-replace-all "\\x0D" res "\\x0D"))
+ res))
diff --git a/clog-window.lisp b/clog-window.lisp
index b2265e9..7c77251 100644
--- a/clog-window.lisp
+++ b/clog-window.lisp
@@ -33,12 +33,12 @@
window."))
(defmethod window-name ((obj clog-window))
- (property obj "name"))
+ (query obj "name"))
(defgeneric set-window-name (clog-window value))
(defmethod set-window-name ((obj clog-window) value)
- (setf (property obj "name") value))
+ (execute obj "name" (escape-string value)))
(defsetf window-name set-window-name)
;;;;;;;;;;;;;;;;
@@ -49,12 +49,12 @@ window."))
(:documentation "Get/Setf status bar text."))
(defmethod status-bar ((obj clog-window))
- (property obj "status"))
+ (query obj "status"))
(defgeneric set-status-bar (clog-window value))
(defmethod set-status-bar ((obj clog-window) value)
- (setf (property obj "status") value))
+ (execute obj "status" (escape-string value)))
(defsetf status-bar set-status-bar)
;;;;;;;;;;;;;;;;;;
@@ -65,12 +65,12 @@ window."))
(:documentation "Get/Setf inner height of browser window."))
(defmethod inner-height ((obj clog-window))
- (property obj "innerHeight"))
+ (query obj "innerHeight"))
(defgeneric set-inner-height (clog-window value))
(defmethod set-inner-height ((obj clog-window) value)
- (setf (property obj "innerHeight") value))
+ (execute obj "innerHeight" value))
(defsetf inner-height set-inner-height)
;;;;;;;;;;;;;;;;;
@@ -81,12 +81,12 @@ window."))
(:documentation "Get/Setf inner width of browser window."))
(defmethod inner-width ((obj clog-window))
- (property obj "innerWidth"))
+ (query obj "innerWidth"))
(defgeneric set-inner-width (clog-window value))
(defmethod set-inner-width ((obj clog-window) value)
- (setf (property obj "innerWidth") value))
+ (execute obj "innerWidth" value))
(defsetf inner-width set-inner-width)
;;;;;;;;;;;;;;;;;;
@@ -97,12 +97,12 @@ window."))
(:documentation "Get/Setf outer height of browser window."))
(defmethod outer-height ((obj clog-window))
- (property obj "outerHeight"))
+ (query obj "outerHeight"))
(defgeneric set-outer-height (clog-window value))
(defmethod set-outer-height ((obj clog-window) value)
- (setf (property obj "outerHeight") value))
+ (execute obj "outerHeight" value))
(defsetf outer-height set-outer-height)
;;;;;;;;;;;;;;;;;
@@ -113,12 +113,12 @@ window."))
(:documentation "Get/Setf outer width of browser window."))
(defmethod outer-width ((obj clog-window))
- (property obj "outerWidth"))
+ (query obj "outerWidth"))
(defgeneric set-outer-width (clog-window value))
(defmethod set-outer-width ((obj clog-window) value)
- (setf (property obj "outerWidth") value))
+ (execute obj "outerWidth" value))
(defsetf outer-width set-outer-width)
;;;;;;;;;;;;;;
@@ -129,12 +129,12 @@ window."))
(:documentation "Get/Setf browser window x offset from left edge."))
(defmethod x-offset ((obj clog-window))
- (property obj "pageXOffset"))
+ (query obj "pageXOffset"))
(defgeneric set-x-offset (clog-window value))
(defmethod set-x-offset ((obj clog-window) value)
- (setf (property obj "pageXOffset") value))
+ (execute obj "pageXOffset" value))
(defsetf x-offset set-x-offset)
;;;;;;;;;;;;;;
@@ -145,13 +145,13 @@ window."))
(:documentation "Get/Setf browser window y offset from top edge."))
(defmethod y-offset ((obj clog-window))
- (property obj "pageYOffset"))
+ (query obj "pageYOffset"))
(defgeneric set-y-offset (clog-window value))
(defmethod set-y-offset ((obj clog-window) value)
- (setf (property obj "pageYOffset") value))
+ (execute obj "pageYOffset" value))
(defsetf y-offset set-y-offsett)
;;;;;;;;;
@@ -162,12 +162,12 @@ window."))
(:documentation "Get/Setf browser y postion."))
(defmethod top ((obj clog-window))
- (property obj "screenY"))
+ (query obj "screenY"))
(defgeneric set-top (clog-window value))
(defmethod set-top ((obj clog-window) value)
- (setf (property obj "screenY") value))
+ (exectue obj "screenY" value))
(defsetf top set-top)
;;;;;;;;;;
@@ -178,12 +178,12 @@ window."))
(:documentation "Get/Setf browser x position."))
(defmethod left ((obj clog-window))
- (property obj "screenX"))
+ (query obj "screenX"))
(defgeneric set-left (clog-window value))
(defmethod set-left ((obj clog-window) value)
- (setf (property obj "screenX") value))
+ (execute obj "screenX" value))
(defsetf left set-x-offset)
;;;;;;;;;;;;;;;;;
@@ -194,7 +194,7 @@ window."))
(:documentation "Get device pixel ratio."))
(defmethod pixel-ratio ((obj clog-window))
- (property obj "devicePixelRatio"))
+ (query obj "devicePixelRatio"))
;;;;;;;;;;;
;; alert ;;
@@ -205,7 +205,7 @@ window."))
events and messages may not be trasmitted on most browsers."))
(defmethod alert ((obj clog-window) message)
- (cc:alert-box (connection-id obj) message))
+ (execute obj (format nil "alert('~A');" (escape-string message))))
;;;;;;;;;;;;;;;;;
;; log-console ;;
@@ -215,8 +215,8 @@ events and messages may not be trasmitted on most browsers."))
(:documentation "Print message to browser console."))
(defmethod log-console ((obj clog-window) message)
- (cc:execute (connection-id obj) (format nil "console.log('~A')"
- (cc:escape-string message))))
+ (execute obj (format nil "console.log('~A')"
+ (escape-string message))))
;;;;;;;;;;;;;;;
;; log-error ;;
@@ -226,8 +226,8 @@ events and messages may not be trasmitted on most browsers."))
(:documentation "Print error message to browser console."))
(defmethod log-error ((obj clog-window) message)
- (cc:execute (connection-id obj) (format nil "console.error('~A')"
- (cc:escape-string message))))
+ (execute obj (format nil "console.error('~A')"
+ (escape-string message))))
;;;;;;;;;;;;;;;;;;
;; print-window ;;
@@ -237,7 +237,7 @@ events and messages may not be trasmitted on most browsers."))
(:documentation "Send browser window to printer."))
(defmethod print-window ((obj clog-window))
- (cc:execute (connection-id obj) "print()"))
+ (execute obj "print()"))
;;;;;;;;;;;;;;;
;; Scroll-by ;;
@@ -247,7 +247,7 @@ events and messages may not be trasmitted on most browsers."))
(:documentation "Scroll browser window by x y."))
(defmethod scroll-by ((obj clog-window) x y)
- (jquery-execute obj (format nil "scrollBy(~A,~A)" x y)))
+ (execute obj (format nil "scrollBy(~A,~A)" x y)))
;;;;;;;;;;;;;;;
;; scroll-to ;;
@@ -257,7 +257,7 @@ events and messages may not be trasmitted on most browsers."))
(:documentation "Scroll browser window to x y."))
(defmethod scroll-to ((obj clog-window) x y)
- (jquery-execute obj (format nil "scrollTo(~A,~A)" x y)))
+ (execute obj (format nil "scrollTo(~A,~A)" x y)))
;;;;;;;;;;;;;;;;;;
;; close-window ;;
@@ -267,7 +267,7 @@ events and messages may not be trasmitted on most browsers."))
(:documentation "Close browser window."))
(defmethod close-window ((obj clog-window))
- (jquery-execute obj "close()"))
+ (execute obj "close()"))
;;;;;;;;;;;;;;;;;;;;;;
;; close-connection ;;
@@ -360,6 +360,20 @@ 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
+ "+ e.originalEvent.key + ':' +
+ e.originalEvent.oldValue + ':' +
+ e.originalEvent.newValue + ':'")
+
+(defun parse-storage-event (data)
+ (let ((f (ppcre:split ":" data)))
+ (list
+ :key-value (nth 0 f)
+ :old-value (nth 1 f)
+ :new-value (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."))
@@ -368,8 +382,8 @@ ON-STORAGE-HANDLER is nil unbind the event."))
(let ((on-storage on-storage-handler))
(set-event obj "storage"
(lambda (data)
- (declare (ignore data))
- (funcall on-storage)))))
+ (funcall on-storage (parse-storage-event data)))
+ :call-back-script storage-event-script)))
;;;;;;;;;;;;;;;;;;;
;; Set-on-resize ;;
diff --git a/clog.lisp b/clog.lisp
index 69250fe..292f7e6 100644
--- a/clog.lisp
+++ b/clog.lisp
@@ -43,8 +43,9 @@ application."
(defsection @clog-utilities (:title "CLOG Utilities")
"CLOG utilities"
- (js-true-p function)
- (open-browser function))
+ (js-true-p function)
+ (open-browser function)
+ (escape-string function))
(defsection @clog-obj (:title "CLOG Objects")
"CLOG-Obj - Base class for CLOG Objects"
@@ -161,7 +162,23 @@ application."
(defsection @clog-document (:title "CLOG Document Objects")
"CLOG-Document - CLOG Document Objects"
- (clog-document class))
+ (clog-document class)
+
+ (domain generic-function)
+ (input-encoding generic-function)
+ (last-modified generic-function)
+ (referrer generic-function)
+ (title generic-function)
+ (url generic-function)
+ (head-element generic-function)
+ (body-element generic-function)
+ (document-element generic-function)
+ (ready-state generic-function)
+ (load-css generic-function)
+ (put generic-function)
+ (put-line generic-function)
+ (put-br generic-function)
+ (put-newline generic-function))
(defsection @clog-location (:title "CLOG Location Objects")
"CLOG-Location - CLOG Location Objects"
diff --git a/test/test-clog.lisp b/test/test-clog.lisp
index bc4a9b3..ffe6c14 100644
--- a/test/test-clog.lisp
+++ b/test/test-clog.lisp
@@ -10,6 +10,7 @@
(defun on-new-window (win)
(log-console (window win) "Message!")
(log-error (window win) "Error Log")
+ (put-br (html-document win) "test 1 2 3")
(setf *last-win* win)
(let ((tmp))
(clog-connection:put-line (clog::connection-id win) "")
@@ -39,6 +40,8 @@
(set-on-character win
(lambda (data)
(print data)))
+ (setf (title (html-document win)) "CLOG Test App")
+ (print (title (html-document win)))
))
(defun test ()