;;; -*- mode: Lisp; Syntax: Common-Lisp; -*- ;;; ;;; Copyright (c) 2009 by the authors. ;;; ;;; See LICENCE for details. (in-package :hu.dwim.presentation) ;; we stay with render-xhtml here, because component-environment is ;; reinstated only after us, so the dojo layer is not active yet (def render-xhtml dojo-frame/widget (bind ((application *application*) (application-path (path-of application)) (encoding (or (when *response* (encoding-name-of *response*)) +default-encoding+)) (debug-client-side? (debug-client-side? -self-)) (javascript-supported? (not (request-parameter-value *request* +no-javascript-error-parameter-name+)))) (emit-xhtml-prologue encoding +xhtml-1.1-doctype+) ,(bind (((icon-uri &optional timestamp) (ensure-list (page-icon-uri-of -self-)))) (when icon-uri )) ,(foreach (lambda (entry) (bind (((stylesheet-uri &optional timestamp) (ensure-list entry))) <link (:rel "stylesheet" :type "text/css" :href ,(bind ((uri (hu.dwim.uri:clone-uri stylesheet-uri))) (hu.dwim.uri:prepend-path uri application-path) (when timestamp (append-timestamp-to-uri uri timestamp)) (hu.dwim.uri:print-uri-to-string uri)))>)) (stylesheet-uris-of -self-)) <script (:type +javascript-mime-type+) ,(string+ "djConfig = { baseUrl: '/static/hdws/libraries/" *dojo-directory-name* "dojo/'" ", parseOnLoad: " (to-js-boolean (parse-dojo-widgets-on-load? -self-)) ", isDebug: " (to-js-boolean debug-client-side?) ;; TODO add separate flag for debugAtAllCosts ", debugAtAllCosts: " (to-js-boolean debug-client-side?) ;; TODO locale should come from either the session or from frame/widget ", locale: " (to-js-literal (locale-name (locale (first (ensure-list (default-locale-of application)))))) "}")> <script (:type +javascript-mime-type+ :src ,(bind ((uri (hu.dwim.uri:clone-uri (dojo-release-uri-of -self-)))) ;; we have the dojo release version in the url, so timestamps here are not important (hu.dwim.uri:prepend-path uri application-path) (hu.dwim.uri:append-path uri (if debug-client-side? (dojo-file-name-of -self-) (string+ (dojo-file-name-of -self-) ".uncompressed.js"))) (hu.dwim.uri:print-uri-to-string uri))) ;; it must have an empty body because browsers don't like collapsed <script ... /> in the head ""> ,(foreach (lambda (entry) (bind (((script-uri &optional timestamp) (ensure-list entry))) <script (:type +javascript-mime-type+ :src ,(bind ((uri (hu.dwim.uri:clone-uri script-uri))) (unless (starts-with #\/ (hu.dwim.uri:path-of uri)) (hu.dwim.uri:prepend-path uri application-path)) (when timestamp (append-timestamp-to-uri uri timestamp)) (when debug-client-side? (setf (hu.dwim.uri:query-parameter-value uri "debug") "t")) (hu.dwim.uri:print-uri-to-string uri))) ;; it must have an empty body because browsers don't like collapsed <script ... /> in the head "">)) (script-uris-of -self-))> <body (:class ,(dojo-skin-name-of -self-) :style ,(when javascript-supported? "margin-left: -10000px;")) ;; TODO: this causes problems when content-type is application/xhtml+xml ;; should solve the no javascript issue in a different way ,(when javascript-supported? <noscript <meta (:http-equiv +header/refresh+ :content ,(string+ "0; URL=" (application-relative-path-for-no-javascript-support-error *application*) "?" +no-javascript-error-parameter-name+ "=t"))>> (apply-localization-function 'render-failed-to-load-page) `js-xml(progn ;; don't use any non-standard js stuff for the failed-to-load machinery, because if things go wrong then nothing is guaranteed to be loaded... (defun _wui_handleFailedToLoad () (setf document.location.href document.location.href) (return false)) (bind ((failed-page (document.getElementById ,+page-failed-to-load-id+))) (setf failed-page.style.display "none") (setf document.hdp-failed-to-load-timer (setTimeout (lambda () ;; if things go wrong, at least have a timer that brings stuff back in the view (setf document.body.style.margin "0px") (dolist (child document.body.childNodes) (when child.style (setf child.style.display "none"))) (setf failed-page.style.display "")) ,+page-failed-to-load-grace-period-in-millisecs+))) (on-load (hdp.reset-scroll-position) (setf hdp.session-id ,(or (awhen *session* (id-of it)) "")) (setf hdp.frame-id ,(or (awhen *frame* (id-of it)) "")) (setf hdp.frame-index ,(or (awhen *frame* (frame-index-of it)) ""))))) ;; NOTE: if javascript is turned on in the browser, then just reload without the marker parameter (this might be true after enabling it and pressing refresh) ,(unless javascript-supported? (bind ((href (hu.dwim.uri:print-uri-to-string (clone-request-uri :strip-query-parameters (list +no-javascript-error-parameter-name+))))) `js-xml(setf window.location.href ,href))) <form (:method "post" :enctype #.+form-encoding/multipart-form-data+ ;; NOTE this is needed for default actions. ;; Firefox calls onClick on the single :type "submit" input, so it doesn't need anything special. ;; Chrome on the other hand simply submits the form, so we need to store an url here that points to the next frame, and render an action-id <input > for default actions. See command rendering for that. ,(when *frame* (make-xml-attribute "action" (bind ((frame-uri (make-uri-for-current-application))) (setf (hu.dwim.uri:query-parameter-value frame-uri +frame-index-parameter-name+) (next-frame-index-of *frame*)) (hu.dwim.uri:print-uri-to-string frame-uri))))) <div (:style "display: none") <input (:id #.+scroll-x-parameter-name+ :name #.+scroll-x-parameter-name+ :type "hidden" :value ,(first (ensure-list (parameter-value +scroll-x-parameter-name+))))> <input (:id #.+scroll-y-parameter-name+ :name #.+scroll-y-parameter-name+ :type "hidden" :value ,(first (ensure-list (parameter-value +scroll-y-parameter-name+))))>> ,@(with-xhtml-body-environment () (render-content-for -self-) `js-onload(progn (log.debug "Loaded successfully, clearing the failed to load timer and showing the page") (clearTimeout document.hdp-failed-to-load-timer) (dojo.style document.body "margin" "0px")))>>>))