Photon 1.0.0
Loading...
Searching...
No Matches
BasePhotonWindow.hpp
Go to the documentation of this file.
1/*
2 * =====================================================================
3 *
4 * Photon
5 * Copyright Amlal EL Mahrouss, all rights reserved.
6 *
7 * =====================================================================
8 */
9
10#pragma once
11
12#include <core/Core.hpp>
13#include <core/URL.hpp>
14#include <dom/IDOMObject.hpp>
15#include <dom/IScriptObject.hpp>
17
18#include <sstream>
19#include <string>
20
21namespace Photon
22{
23 namespace Detail
24 {
25#ifdef __PHOTON_APPLE__
26 typedef NSWindow* WindowHandle;
27#else
28 typedef void* WindowHandle;
29#endif
30 } // namespace Detail
31
33 {
34 private:
36 String m_tab_name{"Loading: Photon"};
38 IDOMObject* m_dom{nullptr};
39 RenderSystemTextDOM* m_document_root{nullptr};
40 Detail::WindowHandle m_tab_handle{nullptr};
41
42 public:
43 BasePhotonWindow() = default;
44 virtual ~BasePhotonWindow() = default;
45
47
48 bool load(URL url)
49 {
50 try
51 {
52 m_html_blob = url.fetch();
53 m_tab_url = url;
54
55 m_dom = IDOMObject::make_dom_object(get_html_document(m_html_blob));
56
57 if (!m_dom) return false;
58
59 std::vector<IScriptObject*> deferred;
60
61 if (auto elem_root = m_dom->get_node("head"); elem_root)
62 {
63 String elem_nm;
64
65 for (auto elem = elem_root->first_node(); elem; elem = elem->next_sibling())
66 {
67 elem_nm = elem->name();
68
69 if (elem_nm == "title")
70 {
71 m_tab_name = elem->value();
72 }
73 else if (elem_nm == "script")
74 {
75 if (elem->first_attribute("href"))
76 {
77 String script_src = elem->first_attribute("href")->value();
78
79 if (script_src.starts_with("http://") || script_src.starts_with("https://"))
80 {
81 auto src = m_tab_url.get() + script_src;
82
83 Photon::URL url(m_tab_url.protocol().c_str());
84 url /= src;
85
86 String in;
87
88 in = url.fetch();
89
90 if (!elem->first_attribute("href")->next_attribute("defer"))
91 {
92 auto script_inside = IScriptObject::make_script_object(in);
93
94 if (script_inside)
95 {
96 script_inside->execute();
97 }
98 }
99 else
100 {
101 deferred.push_back(IScriptObject::make_script_object(in));
102 }
103 }
104 }
105
106 if (!elem->first_attribute("defer") && elem->value())
107 {
108 auto script = IScriptObject::make_script_object(elem->value());
109
110 if (script)
111 {
112 script->execute();
113 }
114 }
115 else if (elem->value())
116 {
117 deferred.push_back(IScriptObject::make_script_object(elem->value()));
118 }
119 }
120 }
121 }
122
123 for (auto& script : deferred)
124 {
125 script->execute();
126 }
127
128 deferred.clear();
129
130 m_document_root = new RenderSystemTextDOM();
131
132 if (auto elem_root = m_dom->get_node("body"); elem_root)
133 {
134 int pos_y = 730;
135 int pos_x = 10;
136
137 String elem_nm;
138
139 for (auto elem = elem_root->first_node(); elem; elem = elem->next_sibling())
140 {
141 elem_nm = elem->name();
142
143 if (elem_nm == "h1")
144 {
146
147 text->set_content_text([NSString stringWithUTF8String:elem->value()]);
148 text->set_heading(RenderSystemTextDOM::kHeading1);
149
150 char* v = elem->value();
151
152 pos_y -= 32.0;
153
154 while ((*v) != 0)
155 {
156 if (*v == '\n')
157 pos_y -= 32.0;
158
159 v = ++v;
160 }
161
162 pos_y -= 32.0;
163
164 text->set_position(pos_x, pos_y);
165
166 m_document_root->insert_child_element(text);
167 }
168 else if (elem_nm == "h2")
169 {
171
172 text->set_content_text([NSString stringWithUTF8String:elem->value()]);
173 text->set_heading(RenderSystemTextDOM::kHeading2);
174
175 char* v = elem->value();
176
177 pos_y -= 24.0;
178
179 while ((*v) != 0)
180 {
181 if (*v == '\n')
182 pos_y -= 24.0;
183
184 v = ++v;
185 }
186
187 pos_y -= 24.0;
188
189 text->set_position(pos_x, pos_y);
190
191 m_document_root->insert_child_element(text);
192 }
193 else if (elem_nm == "h3")
194 {
196
197 text->set_content_text([NSString stringWithUTF8String:elem->value()]);
198 text->set_heading(RenderSystemTextDOM::kHeading3);
199
200 pos_y -= 17.8;
201
202 char* v = elem->value();
203
204 while ((*v) != 0)
205 {
206 if (*v == '\n')
207 pos_y -= 17.8;
208
209 v = ++v;
210 }
211
212 pos_y -= 17.8;
213
214 text->set_position(pos_x, pos_y);
215
216 m_document_root->insert_child_element(text);
217 }
218 else if (elem_nm == "h4" || elem_nm == "h5")
219 {
221
222 text->set_content_text([NSString stringWithUTF8String:elem->value()]);
223 text->set_heading((elem_nm == "h4") ? RenderSystemTextDOM::kHeading4
224 : RenderSystemTextDOM::kHeading5);
225
226 pos_y -= 13.28;
227
228 char* v = elem->value();
229
230 while ((*v) != 0)
231 {
232 if (*v == '\n')
233 pos_y -= 13.28;
234
235 v = ++v;
236 }
237
238 pos_y -= 13.28;
239
240 text->set_position(pos_x, pos_y);
241
242 m_document_root->insert_child_element(text);
243 }
244 else if (elem_nm == "br")
245 {
246 pos_y -= 13.28;
247 }
248 else if (elem_nm == "h6")
249 {
251
252 text->set_content_text([NSString stringWithUTF8String:elem->value()]);
253 text->set_heading(RenderSystemTextDOM::kHeading6);
254
255 pos_y -= 12;
256
257 char* v = elem->value();
258
259 while ((*v) != 0)
260 {
261 if (*v == '\n')
262 pos_y -= 12.0;
263
264 v = ++v;
265 }
266
267 pos_y -= 12;
268
269 text->set_position(pos_x, pos_y);
270
271 m_document_root->insert_child_element(text);
272 }
273 else if (elem_nm == "button")
274 {
276
277 text->set_content_text([NSString stringWithUTF8String:elem->value()]);
278 text->set_heading(RenderSystemTextDOM::kHeadingParagraph);
279
280 pos_y -= 50;
281
282 text->set_position(pos_x, pos_y);
283 m_document_root->insert_child_element(text);
284 }
285 else if (elem_nm == "script")
286 {
287 if (elem->first_attribute("href"))
288 {
289 String script_src = elem->first_attribute("href")->value();
290
291 if (script_src.starts_with("http://") || script_src.starts_with("https://"))
292 {
293 auto src = m_tab_url.get() + script_src;
294
295 Photon::URL url(m_tab_url.protocol().c_str());
296 url /= src;
297
298 String in;
299
300 in = url.fetch();
301
302 if (!elem->first_attribute("href")->next_attribute("defer"))
303 {
304 auto script_inside = IScriptObject::make_script_object(in);
305
306 if (script_inside)
307 {
308 script_inside->execute();
309 }
310 }
311 else
312 {
313 deferred.push_back(IScriptObject::make_script_object(in));
314 }
315 }
316 }
317
318 if (!elem->first_attribute("defer") && elem->value())
319 {
320 auto script = IScriptObject::make_script_object(elem->value());
321
322 if (script)
323 {
324 script->execute();
325 }
326 }
327 else if (elem->value())
328 {
329 deferred.push_back(IScriptObject::make_script_object(elem->value()));
330 }
331 }
332 else if (elem_nm == "img")
333 {
335
336 String image_src = elem->first_attribute("src")->value();
337
338 if (!image_src.starts_with("http://") && !image_src.starts_with("https://") &&
339 !image_src.starts_with("file://"))
340 {
341 image_src = m_tab_url.protocol() + "://" + m_tab_url.get() + "/" + image_src;
342 }
343
344 text->set_image_url(
345 [[NSURL alloc] initWithString:[NSString stringWithUTF8String:image_src.c_str()]]);
346 text->set_content_text([NSString stringWithUTF8String:elem->value()]);
347 text->set_heading(RenderSystemTextDOM::kHeadingParagraph);
348
349 pos_y -= text->height();
350
351 text->set_position(pos_x, pos_y);
352
353 m_document_root->insert_child_element(text);
354 }
355 else if (elem_nm == "p" || elem_nm == "b" || elem_nm == "strong")
356 {
358
359 text->set_content_text([NSString stringWithUTF8String:elem->value()]);
360 text->set_heading((elem_nm == "b" || elem_nm == "strong")
361 ? RenderSystemTextDOM::kHeadingBold
362 : RenderSystemTextDOM::kHeadingParagraph);
363
364 pos_y -= 16;
365
366 char* v = elem->value();
367
368 while ((*v) != 0)
369 {
370 if (*v == '\n')
371 pos_y -= 16.0;
372
373 v = ++v;
374 }
375
376 pos_y -= 16;
377
378 text->set_position(pos_x, pos_y);
379
380 m_document_root->insert_child_element(text);
381 }
382 }
383 }
384
385 for (auto& script : deferred)
386 {
387 script->execute();
388 }
389
390 WindowHelper win;
391
392 m_tab_handle = win.tab(m_tab_name);
393 m_document_root->insert_element(m_tab_handle);
394
395 return true;
396 }
397 catch (const std::runtime_error& err)
398 {
399 PHOTON_ERROR(err.what());
400 }
401 catch (...)
402 {
403 }
404
405 return false;
406 }
407
408 void release()
409 {
410 delete m_dom;
411
412 delete m_document_root;
413 m_document_root = nullptr;
414
415 m_html_blob.clear();
416 m_tab_name.clear();
417 }
418 };
419} // namespace Photon
#define PHOTON_ERROR(...)
Definition Core.hpp:165
#define PHOTON_EMPTY_HTML
Definition Core.hpp:24
<script> element.
#define PHOTON_HTTPS_PROTOCOL
Definition URL.hpp:18
Definition BasePhotonWindow.hpp:33
bool load(URL url)
Definition BasePhotonWindow.hpp:48
virtual ~BasePhotonWindow()=default
void release()
Definition BasePhotonWindow.hpp:408
PHOTON_COPY_DEFAULT(BasePhotonWindow)
Definition IDOMObject.hpp:28
Definition RenderSystem+OpenStep.hpp:351
virtual void set_position(CGFloat x, CGFloat y)
Definition RenderSystem+OpenStep.hpp:48
void set_heading(int32_t text)
Definition RenderSystem+OpenStep.hpp:69
virtual void set_content_text(NSString *text)
Definition RenderSystem+OpenStep.hpp:43
Definition RenderSystem+OpenStep.hpp:215
bool set_image_url(NSURL *url_img)
Definition RenderSystem+OpenStep.hpp:229
size_t height()
Definition RenderSystem+OpenStep.hpp:266
Definition RenderSystem+OpenStep.hpp:122
Definition URL.hpp:44
String fetch()
Definition URL.mm:135
Definition Core.hpp:70
NSWindow * tab(const String text)
Definition Core.hpp:103
#define PHOTON_API
Definition Config.hpp:64
#define in
Definition internal.h:15
void * WindowHandle
Definition BasePhotonWindow.hpp:28
This file is also about defining core js concepts.
Definition BasePhotonWindow.hpp:22
String get_html_document(String the_xml_blob)
Get HTML document from xml blob.
Definition IDOMObject.mm:31
std::string String
Definition Core.hpp:37
script
Definition tag_strings.h:11