/src/wt/src/web/WebRenderer.h
Line | Count | Source |
1 | | // This may look like C code, but it's really -*- C++ -*- |
2 | | /* |
3 | | * Copyright (C) 2008 Emweb bv, Herent, Belgium. |
4 | | * |
5 | | * See the LICENSE file for terms of use. |
6 | | */ |
7 | | #ifndef WEBRENDERER_H_ |
8 | | #define WEBRENDERER_H_ |
9 | | |
10 | | #include <string> |
11 | | #include <vector> |
12 | | #include <set> |
13 | | |
14 | | #include "Wt/WDateTime.h" |
15 | | #include "Wt/WEnvironment.h" |
16 | | #include "Wt/WStatelessSlot.h" |
17 | | #include "Wt/Http/Cookie.h" |
18 | | |
19 | | namespace Wt { |
20 | | |
21 | | class WebRequest; |
22 | | class WebResponse; |
23 | | class WebStream; |
24 | | class DomElement; |
25 | | class EscapeOStream; |
26 | | class FileServe; |
27 | | class MetaHeader; |
28 | | |
29 | | class WApplication; |
30 | | class WWidget; |
31 | | class WWebWidget; |
32 | | class WObject; |
33 | | class WResource; |
34 | | class WStatelessSlot; |
35 | | class WWidget; |
36 | | |
37 | | class WT_API WebRenderer : public Wt::SlotLearnerInterface |
38 | | { |
39 | | public: |
40 | | typedef std::map<std::string, WObject *> FormObjectsMap; |
41 | | |
42 | | WebRenderer(WebSession& session); |
43 | | |
44 | | void setTwoPhaseThreshold(int bytes); |
45 | | |
46 | 0 | bool visibleOnly() const { return visibleOnly_; } |
47 | 0 | void setVisibleOnly(bool how) { visibleOnly_ = how; } |
48 | 0 | bool isRendered() const { return rendered_; } |
49 | | void setRendered(bool how); |
50 | | |
51 | | void needUpdate(WWidget *w, bool laterOnly); |
52 | | void doneUpdate(WWidget *w); |
53 | | void updateFormObjects(WWebWidget *w, bool checkDescendants); |
54 | | |
55 | | void updateFormObjectsList(WApplication *app); |
56 | | const FormObjectsMap& formObjects() const; |
57 | | |
58 | | void saveChanges(); |
59 | | void discardChanges(); |
60 | | void letReloadJS(WebResponse& request, bool newSession, |
61 | | bool embedded = false); |
62 | | void letReloadHTML(WebResponse& request, bool newSession); |
63 | | |
64 | | bool isDirty() const; |
65 | 0 | unsigned int scriptId() const { return scriptId_; } |
66 | 0 | int pageId() const { return pageId_; } |
67 | | |
68 | | void serveResponse(WebResponse& request); |
69 | | void serveError(int status, WebResponse& request, |
70 | | const std::string& message); |
71 | | void serveLinkedCss(WebResponse& request); |
72 | | |
73 | | void setCookie(const Http::Cookie& cookie); |
74 | | void removeCookie(const Http::Cookie& cookie); |
75 | | |
76 | 0 | bool preLearning() const { return learning_; } |
77 | | void learningIncomplete(); |
78 | | |
79 | 0 | void updateLayout() { updateLayout_ = true; } |
80 | | |
81 | | enum AckState { |
82 | | CorrectAck, |
83 | | ReasonableAck, |
84 | | BadAck |
85 | | }; |
86 | | |
87 | | AckState ackUpdate(unsigned int updateId); |
88 | | |
89 | | void streamRedirectJS(WStringStream& out, const std::string& redirect); |
90 | | |
91 | | bool checkResponsePuzzle(const WebRequest& request); |
92 | | |
93 | | bool jsSynced() const; |
94 | | |
95 | | void setJSSynced(bool invisibleToo); |
96 | | |
97 | 0 | void setStatelessSlotNotStateless() { currentStatelessSlotIsActuallyStateless_ = false; } |
98 | | |
99 | | #ifndef WT_TARGET_JAVA |
100 | | static std::string renderCookieHttpHeader(const Http::Cookie& cookie, WebSession& session); |
101 | | #endif |
102 | | |
103 | | private: |
104 | | WebSession& session_; |
105 | | |
106 | | bool visibleOnly_, rendered_, initialStyleRendered_; |
107 | | int twoPhaseThreshold_, pageId_, ackErrs_; |
108 | | unsigned int expectedAckId_, scriptId_; |
109 | | int linkedCssCount_; |
110 | | std::string solution_; |
111 | | |
112 | | bool currentStatelessSlotIsActuallyStateless_; |
113 | | |
114 | | std::vector<Http::Cookie> cookiesToSet_; |
115 | | |
116 | | FormObjectsMap currentFormObjects_; |
117 | | std::string currentFormObjectsList_; |
118 | | bool formObjectsChanged_; |
119 | | bool updateLayout_; |
120 | | |
121 | | std::vector<int> wsRequestsToHandle_; |
122 | | bool cookieUpdateNeeded_; |
123 | | |
124 | | void setHeaders(WebResponse& request, const std::string mimeType); |
125 | | void addNoCacheHeaders(WebResponse& response); |
126 | | |
127 | | void serveJavaScriptUpdate(WebResponse& response); |
128 | | void serveMainscript(WebResponse& response); |
129 | | void serveBootstrap(WebResponse& request); |
130 | | void serveMainpage(WebResponse& response); |
131 | | void serveMainAjax(WStringStream& out); |
132 | | void serveWidgetSet(WebResponse& request); |
133 | | void collectJavaScript(); |
134 | | |
135 | | void collectChanges(std::vector<DomElement *>& changes); |
136 | | |
137 | | void collectJavaScriptUpdate(WStringStream& out); |
138 | | void loadStyleSheet(WStringStream& out, WApplication *app, |
139 | | const WLinkedCssStyleSheet& sheet); |
140 | | void loadStyleSheets(WStringStream& out, WApplication *app); |
141 | | void removeStyleSheets(WStringStream& out, WApplication *app); |
142 | | int loadScriptLibraries(WStringStream& out, WApplication *app, |
143 | | int count = -1); |
144 | | void updateLoadIndicator(WStringStream& out, WApplication *app, bool all); |
145 | | void renderSetServerPush(WStringStream& out); |
146 | | void renderStyleSheet(WStringStream& out, const WLinkedCssStyleSheet& sheet, |
147 | | WApplication *app); |
148 | | |
149 | | std::string createFormObjectsList(WApplication *app); |
150 | | |
151 | | void preLearnStateless(WApplication *app, WStringStream& out); |
152 | | WStringStream collectedJS1_, collectedJS2_, invisibleJS_, statelessJS_, |
153 | | beforeLoadJS_; |
154 | | void collectJS(WStringStream *js); |
155 | | |
156 | | void setPageVars(FileServe& page, const std::string& nonce); |
157 | | void streamBootContent(WebResponse& response, |
158 | | FileServe& boot, bool hybrid); |
159 | | void addResponseAckPuzzle(WStringStream& out); |
160 | | void addContainerWidgets(WWebWidget *w, |
161 | | std::vector<WContainerWidget *>& v); |
162 | | |
163 | | std::string headDeclarations() const; |
164 | | std::string bodyClassRtl() const; |
165 | | std::string sessionUrl() const; |
166 | | |
167 | | typedef std::set<WWidget *> UpdateMap; |
168 | | UpdateMap updateMap_; |
169 | | bool learning_, learningIncomplete_, moreUpdates_; |
170 | | |
171 | | std::string safeJsStringLiteral(const std::string& value); |
172 | | |
173 | | void addWsRequestId(int wsRqId); |
174 | | void renderWsRequestsDone(WStringStream &out); |
175 | | |
176 | | void updateMultiSessionCookie(const WebRequest &request); |
177 | | void renderCookieUpdate(WStringStream &out); |
178 | | |
179 | | /* |
180 | | * See how large the invisible changes are, perhaps we can |
181 | | * send them along in the first request. |
182 | | */ |
183 | | void preCollectInvisibleChanges(); |
184 | | |
185 | | public: |
186 | | virtual std::string learn(WStatelessSlot* slot) final override; |
187 | | |
188 | | friend class WApplication; |
189 | | friend class WebSession; |
190 | | }; |
191 | | |
192 | | } |
193 | | |
194 | | #endif // WEBRENDERER_H_ |