| 359 | | #| |
| 360 | | (defclass message-dispatcher () |
| 361 | | () |
| 362 | | (:documentation "This is and interface for message dispatchers")) |
| 363 | | |
| 364 | | (defclass simple-message-dispatcher (message-dispatcher) |
| 365 | | ((locales :initform (make-hash-table :test #'equal) |
| 366 | | :accessor simple-message-dispatcher-locales |
| 367 | | :documentation "Hash table of locales strings and KEY/VALUE message pairs")) |
| 368 | | (:documentation "A message disptcher that leave data unchanged during encoding and decoding phases.")) |
| 369 | | |
| 370 | | (defclass i18n-aware (message-dispatcher) |
| 371 | | ((message-dispatcher :initarg :message-dispatcher |
| 372 | | :accessor message-dispatcher |
| 373 | | :documentation "Reference to a MESSAGE-DISPATCHER instance")) |
| 374 | | (:default-initargs :message-dispatcher nil) |
| 375 | | (:documentation "All classes that need to dispatch messages are subclasses of I18N-AWARE")) |
| 376 | | |# |
| 671 | | (if (null body) |
| 672 | | (format nil "null body for page ~a~%" (type-of page)) |
| 673 | | (progn |
| 674 | | (page-init page) |
| 675 | | (when (page-req-parameter page *rewind-parameter*) |
| 676 | | (htcomponent-rewind body page)) |
| 677 | | (page-init page) |
| 678 | | (htcomponent-prerender (page-content page) page) ;Here we need a fresh new body!!! |
| 679 | | (page-render-headings page) |
| 680 | | (page-init page) |
| 681 | | (when jsonp |
| 682 | | (page-format-raw page (page-json-prefix page)) |
| 683 | | (page-format-raw page "{components:{")) |
| 684 | | (htcomponent-render (page-content page) page) ;Here we need a fresh new body!!! |
| 685 | | (when jsonp |
| 686 | | (page-format-raw page "},classInjections:\"") |
| 687 | | (setf (page-can-print page) t |
| 688 | | (page-injection-writing-p page) t) |
| 689 | | (dolist (injection (page-init-injections page)) |
| 690 | | (when injection |
| 691 | | (htcomponent-render injection page))) |
| 692 | | (page-format-raw page "\",instanceInjections:\"") |
| 693 | | (let ((init-scripts (htbody-init-scripts-tag page))) |
| 694 | | (when init-scripts |
| 695 | | (htcomponent-render init-scripts page))) |
| 696 | | (page-format-raw page "\",errors:") |
| 697 | | (page-format-raw page (json-validation-errors)) |
| 698 | | (page-format-raw page ",valid:") |
| 699 | | (page-format-raw page (json-validation-compliances)) |
| 700 | | (page-format-raw page "}") |
| 701 | | (page-format-raw page (page-json-suffix page))))))) |
| | 671 | (progn |
| | 672 | (page-init page) |
| | 673 | (page-before-render page) |
| | 674 | (when (page-req-parameter page *rewind-parameter*) |
| | 675 | (htcomponent-rewind (page-content page) page)) |
| | 676 | (page-init page) |
| | 677 | (htcomponent-prerender (page-content page) page) ;Here we need a fresh new body!!! |
| | 678 | (page-render-headings page) |
| | 679 | (page-init page) |
| | 680 | (when jsonp |
| | 681 | (page-format-raw page (page-json-prefix page)) |
| | 682 | (page-format-raw page "{components:{")) |
| | 683 | (htcomponent-render (page-content page) page) ;Here we need a fresh new body!!! |
| | 684 | (when jsonp |
| | 685 | (page-format-raw page "},classInjections:\"") |
| | 686 | (setf (page-can-print page) t |
| | 687 | (page-injection-writing-p page) t) |
| | 688 | (dolist (injection (page-init-injections page)) |
| | 689 | (when injection |
| | 690 | (htcomponent-render injection page))) |
| | 691 | (page-format-raw page "\",instanceInjections:\"") |
| | 692 | (let ((init-scripts (htbody-init-scripts-tag page))) |
| | 693 | (when init-scripts |
| | 694 | (htcomponent-render init-scripts page))) |
| | 695 | (page-format-raw page "\",errors:") |
| | 696 | (page-format-raw page (json-validation-errors)) |
| | 697 | (page-format-raw page ",valid:") |
| | 698 | (page-format-raw page (json-validation-compliances)) |
| | 699 | (page-format-raw page "}") |
| | 700 | (page-format-raw page (page-json-suffix page)))))) |
| 760 | | (let* ((id (when (slot-boundp htcomponent 'client-id) (htcomponent-client-id htcomponent))) |
| 761 | | (page (htcomponent-page htcomponent)) |
| 762 | | (print-status (page-can-print page)) |
| 763 | | (validation-errors *validation-errors*) |
| 764 | | (json-render-on-validation-errors-p (htcomponent-json-render-on-validation-errors-p htcomponent)) |
| 765 | | (render-p (or (and (member id (page-json-id-list page) :test #'string=) |
| 766 | | (null validation-errors)) |
| 767 | | print-status))) |
| 768 | | (or json-render-on-validation-errors-p print-status render-p))) |
| | 759 | (let* ((id (when (slot-boundp htcomponent 'client-id) |
| | 760 | (htcomponent-client-id htcomponent))) |
| | 761 | (page (htcomponent-page htcomponent)) |
| | 762 | (print-status (page-can-print page)) |
| | 763 | (validation-errors *validation-errors*) |
| | 764 | (json-render-on-validation-errors-p (htcomponent-json-render-on-validation-errors-p htcomponent)) |
| | 765 | (render-p (or (and (member id (page-json-id-list page) :test #'string=) |
| | 766 | (null validation-errors)) |
| | 767 | print-status))) |
| | 768 | (or json-render-on-validation-errors-p print-status render-p))) |
| 771 | | (let* ((page (htcomponent-page htcomponent)) |
| 772 | | (jsonp (page-json-id-list page)) |
| 773 | | (id (when (slot-boundp htcomponent 'client-id) (htcomponent-client-id htcomponent))) |
| 774 | | (validation-errors *validation-errors*)) |
| 775 | | (when (and jsonp |
| 776 | | (or (and (null validation-errors) |
| 777 | | (member id jsonp :test #'string-equal)) |
| 778 | | (htcomponent-json-render-on-validation-errors-p htcomponent))) |
| 779 | | (when (> (page-json-component-count page) 0) |
| 780 | | (page-format page ",")) |
| 781 | | (page-format-raw page "~a:\"" id) |
| 782 | | (push id (page-json-component-id-list page)) |
| 783 | | (incf (page-json-component-count page))))) |
| | 771 | (let* ((page (htcomponent-page htcomponent)) |
| | 772 | (jsonp (page-json-id-list page)) |
| | 773 | (id (when (slot-boundp htcomponent 'client-id) |
| | 774 | (htcomponent-client-id htcomponent))) |
| | 775 | (validation-errors *validation-errors*)) |
| | 776 | (when (and jsonp |
| | 777 | (or (and (null validation-errors) |
| | 778 | (member id jsonp :test #'string-equal)) |
| | 779 | (htcomponent-json-render-on-validation-errors-p htcomponent))) |
| | 780 | (when (> (page-json-component-count page) 0) |
| | 781 | (page-format page ",")) |
| | 782 | (page-format-raw page "~a:\"" id) |
| | 783 | (push id (page-json-component-id-list page)) |
| | 784 | (incf (page-json-component-count page))))) |
| 786 | | (let* ((page (htcomponent-page htcomponent)) |
| 787 | | (jsonp (page-json-id-list page)) |
| 788 | | (id (when (slot-boundp htcomponent 'client-id) (htcomponent-client-id htcomponent))) |
| 789 | | (validation-errors *validation-errors*)) |
| 790 | | (when (and jsonp |
| 791 | | (or (and (null validation-errors) |
| 792 | | (member id jsonp :test #'string-equal)) |
| 793 | | (htcomponent-json-render-on-validation-errors-p htcomponent))) |
| 794 | | (pop (page-json-component-id-list page)) |
| 795 | | (page-format-raw page "\"")))) |
| | 787 | (let* ((page (htcomponent-page htcomponent)) |
| | 788 | (jsonp (page-json-id-list page)) |
| | 789 | (id (when (slot-boundp htcomponent 'client-id) (htcomponent-client-id htcomponent))) |
| | 790 | (validation-errors *validation-errors*)) |
| | 791 | (when (and jsonp |
| | 792 | (or (and (null validation-errors) |
| | 793 | (member id jsonp :test #'string-equal)) |
| | 794 | (htcomponent-json-render-on-validation-errors-p htcomponent))) |
| | 795 | (pop (page-json-component-id-list page)) |
| | 796 | (page-format-raw page "\"")))) |
| 832 | | (let ((previous-print-status (page-can-print page)) |
| 833 | | (render-condition (htcomponent-render-condition htcomponent))) |
| 834 | | (unless (and render-condition (null (funcall render-condition))) |
| 835 | | (when (null previous-print-status) |
| 836 | | (setf (page-can-print page) (htcomponent-can-print htcomponent))) |
| 837 | | (dolist (tag (htcomponent-body htcomponent)) |
| 838 | | (when (subtypep (type-of tag) 'htcomponent) |
| 839 | | (htcomponent-prerender tag page))) |
| 840 | | (when (null previous-print-status) |
| 841 | | (setf (page-can-print page) nil))))) |
| | 833 | (let ((previous-print-status (page-can-print page)) |
| | 834 | (render-condition (htcomponent-render-condition htcomponent))) |
| | 835 | (unless (and render-condition (null (funcall render-condition))) |
| | 836 | (when (null previous-print-status) |
| | 837 | (setf (page-can-print page) (htcomponent-can-print htcomponent))) |
| | 838 | (dolist (tag (htcomponent-body htcomponent)) |
| | 839 | (when (subtypep (type-of tag) 'htcomponent) |
| | 840 | (htcomponent-prerender tag page))) |
| | 841 | (when (null previous-print-status) |
| | 842 | (setf (page-can-print page) nil))))) |
| 844 | | (let ((body-list (htcomponent-body htcomponent)) |
| 845 | | (previous-print-status (page-can-print page)) |
| 846 | | (render-condition (htcomponent-render-condition htcomponent))) |
| 847 | | (unless (and render-condition (null (funcall render-condition))) |
| 848 | | (when (null previous-print-status) |
| 849 | | (setf (page-can-print page) (htcomponent-can-print htcomponent)) |
| 850 | | (htcomponent-json-print-start-component htcomponent)) |
| 851 | | (dolist (child-tag body-list) |
| 852 | | (when child-tag |
| 853 | | (cond |
| 854 | | ((stringp child-tag) (htcomponent-render ($> child-tag) page)) |
| 855 | | ((functionp child-tag) (htcomponent-render ($> (funcall child-tag)) page)) |
| 856 | | (t (htcomponent-render child-tag page))))) |
| 857 | | (when (null previous-print-status) |
| 858 | | (setf (page-can-print page) nil) |
| 859 | | (htcomponent-json-print-end-component htcomponent))))) |
| | 845 | (let ((body-list (htcomponent-body htcomponent)) |
| | 846 | (previous-print-status (page-can-print page)) |
| | 847 | (render-condition (htcomponent-render-condition htcomponent))) |
| | 848 | (unless (and render-condition (null (funcall render-condition))) |
| | 849 | (when (null previous-print-status) |
| | 850 | (setf (page-can-print page) (htcomponent-can-print htcomponent)) |
| | 851 | (htcomponent-json-print-start-component htcomponent)) |
| | 852 | (dolist (child-tag body-list) |
| | 853 | (when child-tag |
| | 854 | (cond |
| | 855 | ((stringp child-tag) (htcomponent-render ($> child-tag) page)) |
| | 856 | ((functionp child-tag) (htcomponent-render ($> (funcall child-tag)) page)) |
| | 857 | (t (htcomponent-render child-tag page))))) |
| | 858 | (when (null previous-print-status) |
| | 859 | (setf (page-can-print page) nil) |
| | 860 | (htcomponent-json-print-end-component htcomponent))))) |
| 866 | | (when (htcomponent-attributes tag) |
| 867 | | (loop for (k v) on (htcomponent-attributes tag) by #'cddr |
| 868 | | do (progn |
| 869 | | (assert (keywordp k)) |
| 870 | | (when (and (functionp v) (not (eq k :render-condition))) |
| 871 | | (setf v (funcall v))) |
| 872 | | (when (numberp v) |
| 873 | | (setf v (princ-to-string v))) |
| 874 | | (when (and (not (eq k :render-condition)) v (string-not-equal v "")) |
| 875 | | (page-format page " ~a=\"~a\"" |
| 876 | | (if (eq k :static-id) |
| 877 | | "id" |
| 878 | | (parenscript::symbol-to-js k)) |
| 879 | | (let ((s (if (eq k :id) |
| 880 | | (prin1-to-string (htcomponent-client-id tag)) |
| 881 | | (if (eq t v) |
| 882 | | "\"true\"" |
| 883 | | (prin1-to-string v))))) ;escapes double quotes |
| 884 | | (subseq s 1 (1- (length s)))))))))) |
| | 867 | (when (htcomponent-attributes tag) |
| | 868 | (loop for (k v) on (htcomponent-attributes tag) by #'cddr |
| | 869 | do (progn |
| | 870 | (assert (keywordp k)) |
| | 871 | (when (and (functionp v) (not (eq k :render-condition))) |
| | 872 | (setf v (funcall v))) |
| | 873 | (when (numberp v) |
| | 874 | (setf v (princ-to-string v))) |
| | 875 | (when (and (not (eq k :render-condition)) v (string-not-equal v "")) |
| | 876 | (page-format page " ~a=\"~a\"" |
| | 877 | (if (eq k :static-id) |
| | 878 | "id" |
| | 879 | (parenscript::symbol-to-js k)) |
| | 880 | (let ((s (if (eq k :id) |
| | 881 | (prin1-to-string (htcomponent-client-id tag)) |
| | 882 | (if (eq t v) |
| | 883 | "\"true\"" |
| | 884 | (prin1-to-string v))))) ;escapes double quotes |
| | 885 | (subseq s 1 (1- (length s)))))))))) |
| 887 | | (let ((tagname (tag-name tag)) |
| 888 | | (id (when (slot-boundp tag 'client-id) (htcomponent-client-id tag))) |
| 889 | | (jsonp (page-json-id-list page)) |
| 890 | | (emptyp (htcomponent-empty tag)) |
| 891 | | (xml-p (page-xmloutput page)) |
| 892 | | (injection-writing-p (page-injection-writing-p page))) |
| 893 | | (setf (page-lasttag page) tagname) |
| 894 | | (when (or injection-writing-p |
| 895 | | (null jsonp) |
| 896 | | (null (and jsonp |
| 897 | | (string= id (first (page-json-component-id-list page)))))) |
| 898 | | (page-newline page) |
| 899 | | (page-print-tabulation page) |
| 900 | | (page-format page "<~a" tagname) |
| 901 | | (tag-render-attributes tag page) |
| 902 | | (if (null emptyp) |
| | 888 | (let ((tagname (tag-name tag)) |
| | 889 | (id (when (slot-boundp tag 'client-id) (htcomponent-client-id tag))) |
| | 890 | (jsonp (page-json-id-list page)) |
| | 891 | (emptyp (htcomponent-empty tag)) |
| | 892 | (xml-p (page-xmloutput page)) |
| | 893 | (injection-writing-p (page-injection-writing-p page))) |
| | 894 | (setf (page-lasttag page) tagname) |
| | 895 | (when (or injection-writing-p |
| | 896 | (null jsonp) |
| | 897 | (null (and jsonp |
| | 898 | (string= id (first (page-json-component-id-list page)))))) |
| | 899 | (page-newline page) |
| | 900 | (page-print-tabulation page) |
| | 901 | (page-format page "<~a" tagname) |
| | 902 | (tag-render-attributes tag page) |
| | 903 | (if (null emptyp) |
| | 904 | (progn |
| | 905 | (page-format page ">") |
| | 906 | (incf (page-tabulator page))) |
| | 907 | (if (null xml-p) |
| | 908 | (page-format page ">") |
| | 909 | (page-format page "/>")))))) |
| | 910 | |
| | 911 | (defmethod tag-render-endtag ((tag tag) (page page)) |
| | 912 | (let ((tagname (tag-name tag)) |
| | 913 | (id (when (slot-boundp tag 'client-id) (htcomponent-client-id tag))) |
| | 914 | (jsonp (page-json-id-list page)) |
| | 915 | (previous-tagname (page-lasttag page)) |
| | 916 | (emptyp (htcomponent-empty tag)) |
| | 917 | (injection-writing-p (page-injection-writing-p page))) |
| | 918 | (when (and (null emptyp) |
| | 919 | (or injection-writing-p |
| | 920 | (null jsonp) |
| | 921 | (null (and jsonp |
| | 922 | (string= id (first (page-json-component-id-list page))))))) |
| | 923 | (progn |
| | 924 | (decf (page-tabulator page)) |
| | 925 | (if (string= tagname previous-tagname) |
| 904 | | (page-format page ">") |
| 905 | | (incf (page-tabulator page))) |
| 906 | | (if (null xml-p) |
| 907 | | (page-format page ">") |
| 908 | | (page-format page "/>")))))) |
| 909 | | |
| 910 | | (defmethod tag-render-endtag ((tag tag) (page page)) |
| 911 | | (let ((tagname (tag-name tag)) |
| 912 | | (id (when (slot-boundp tag 'client-id) (htcomponent-client-id tag))) |
| 913 | | (jsonp (page-json-id-list page)) |
| 914 | | (previous-tagname (page-lasttag page)) |
| 915 | | (emptyp (htcomponent-empty tag)) |
| 916 | | (injection-writing-p (page-injection-writing-p page))) |
| 917 | | (when (and (null emptyp) |
| 918 | | (or injection-writing-p |
| 919 | | (null jsonp) |
| 920 | | (null (and jsonp |
| 921 | | (string= id (first (page-json-component-id-list page))))))) |
| 922 | | (progn |
| 923 | | (decf (page-tabulator page)) |
| 924 | | (if (string= tagname previous-tagname) |
| 925 | | (progn |
| 926 | | (page-format page "</~a>" tagname)) |
| 927 | | (progn |
| 928 | | (page-newline page) |
| 929 | | (page-print-tabulation page) |
| 930 | | (page-format page "</~a>" tagname))))) |
| 931 | | (setf (page-lasttag page) nil))) |
| | 927 | (page-format page "</~a>" tagname)) |
| | 928 | (progn |
| | 929 | (page-newline page) |
| | 930 | (page-print-tabulation page) |
| | 931 | (page-format page "</~a>" tagname))))) |
| | 932 | (setf (page-lasttag page) nil))) |
| 934 | | (let ((body-list (htcomponent-body tag)) |
| 935 | | (previous-print-status (page-can-print page)) |
| 936 | | (render-condition (htcomponent-render-condition tag))) |
| 937 | | (unless (and render-condition (null (funcall render-condition))) |
| 938 | | (when (null previous-print-status) |
| 939 | | (setf (page-can-print page) (htcomponent-can-print tag)) |
| 940 | | (htcomponent-json-print-start-component tag)) |
| 941 | | (when (or (page-can-print page) previous-print-status) |
| 942 | | (tag-render-starttag tag page)) |
| 943 | | (dolist (child-tag body-list) |
| 944 | | (when child-tag |
| 945 | | (cond |
| 946 | | ((stringp child-tag) (htcomponent-render ($> child-tag) page)) |
| 947 | | ((functionp child-tag) (htcomponent-render ($> (funcall child-tag)) page)) |
| 948 | | (t (htcomponent-render child-tag page))))) |
| 949 | | (when (or (page-can-print page) previous-print-status) |
| 950 | | (tag-render-endtag tag page)) |
| 951 | | (unless previous-print-status |
| 952 | | (setf (page-can-print page) nil) |