NetSurf
dom_event.c
Go to the documentation of this file.
1/*
2 * Copyright 2010 Michael Drake <tlsa@netsurf-browser.org>
3 * Copyright 2020 Vincent Sanders <vince@netsurf-browser.org>
4 *
5 * This file is part of NetSurf, http://www.netsurf-browser.org/
6 *
7 * NetSurf is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * NetSurf is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20/**
21 * \file
22 * Implementation of HTML content DOM event handling.
23 */
24
25#include <string.h>
26
27#include "utils/config.h"
28#include "utils/utils.h"
29#include "utils/corestrings.h"
30#include "utils/nsoption.h"
31#include "utils/log.h"
32#include "utils/ascii.h"
33#include "utils/string.h"
34#include "utils/nsurl.h"
35#include "content/content.h"
36#include "javascript/js.h"
37
38#include "netsurf/bitmap.h"
39
40#include "html/private.h"
41#include "html/object.h"
42#include "html/css.h"
43#include "html/box.h"
44#include "html/box_construct.h"
45#include "html/form_internal.h"
46#include "html/dom_event.h"
47
48
49/**
50 * process a base element being inserted into the DOM
51 *
52 * \param htmlc The html content containing the DOM
53 * \param node The DOM node being inserted
54 * \return NSERROR_OK on success else appropriate error code
55 */
56static bool html_process_inserted_base(html_content *htmlc, dom_node *node)
57{
58 dom_exception exc; /* returned by libdom functions */
59 dom_string *atr_string;
60
61 /* get href attribute if present */
62 exc = dom_element_get_attribute(node, corestring_dom_href, &atr_string);
63 if ((exc == DOM_NO_ERR) && (atr_string != NULL)) {
64 nsurl *url;
65 nserror error;
66
67 /* get url from string */
68 error = nsurl_create(dom_string_data(atr_string), &url);
69 dom_string_unref(atr_string);
70 if (error == NSERROR_OK) {
71 if (htmlc->base_url != NULL) {
72 nsurl_unref(htmlc->base_url);
73 }
74 htmlc->base_url = url;
75 }
76 }
77
78
79 /* get target attribute if present and not already set */
80 if (htmlc->base_target != NULL) {
81 return true;
82 }
83
84 exc = dom_element_get_attribute(node,
85 corestring_dom_target,
86 &atr_string);
87 if ((exc == DOM_NO_ERR) && (atr_string != NULL)) {
88 /* Validation rules from the HTML5 spec for the base element:
89 * The target must be one of _blank, _self, _parent, or
90 * _top or any identifier which does not begin with an
91 * underscore
92 */
93 if (*dom_string_data(atr_string) != '_' ||
94 dom_string_caseless_lwc_isequal(atr_string,
95 corestring_lwc__blank) ||
96 dom_string_caseless_lwc_isequal(atr_string,
97 corestring_lwc__self) ||
98 dom_string_caseless_lwc_isequal(atr_string,
99 corestring_lwc__parent) ||
100 dom_string_caseless_lwc_isequal(atr_string,
101 corestring_lwc__top)) {
102 htmlc->base_target = strdup(dom_string_data(atr_string));
103 }
104 dom_string_unref(atr_string);
105 }
106
107 return true;
108}
109
110
111
112/**
113 * Process img element being inserted into the DOM.
114 *
115 * \param htmlc The html content containing the DOM
116 * \param node The DOM node being inserted
117 * \return NSERROR_OK on success else appropriate error code
118 */
119static bool html_process_inserted_img(html_content *htmlc, dom_node *node)
120{
121 dom_string *src;
122 nsurl *url;
123 nserror err;
124 dom_exception exc;
125 bool success;
126
127 /* Do nothing if foreground images are disabled */
128 if (nsoption_bool(foreground_images) == false) {
129 return true;
130 }
131
132 exc = dom_element_get_attribute(node, corestring_dom_src, &src);
133 if (exc != DOM_NO_ERR || src == NULL) {
134 return true;
135 }
136
137 err = nsurl_join(htmlc->base_url, dom_string_data(src), &url);
138 if (err != NSERROR_OK) {
139 dom_string_unref(src);
140 return false;
141 }
142 dom_string_unref(src);
143
144 /* Speculatively fetch the image */
145 success = html_fetch_object(htmlc, url, NULL, CONTENT_IMAGE, false);
146 nsurl_unref(url);
147
148 return success;
149}
150
151
152/**
153 * process a LINK element being inserted into the DOM
154 *
155 * \note only the http-equiv attribute for refresh is currently considered
156 *
157 * \param htmlc The html content containing the DOM
158 * \param n The DOM node being inserted
159 * \return NSERROR_OK on success else appropriate error code
160 */
161static bool html_process_inserted_link(html_content *c, dom_node *node)
162{
163 struct content_rfc5988_link link; /* the link added to the content */
164 dom_exception exc; /* returned by libdom functions */
165 dom_string *atr_string;
166 nserror error;
167
168 /* Handle stylesheet loading */
169 html_css_process_link(c, (dom_node *)node);
170
171 /* try Generic link handling */
172
173 memset(&link, 0, sizeof(struct content_rfc5988_link));
174
175 /* check that the relation exists - w3c spec says must be present */
176 exc = dom_element_get_attribute(node, corestring_dom_rel, &atr_string);
177 if ((exc != DOM_NO_ERR) || (atr_string == NULL)) {
178 return false;
179 }
180 /* get a lwc string containing the link relation */
181 exc = dom_string_intern(atr_string, &link.rel);
182 dom_string_unref(atr_string);
183 if (exc != DOM_NO_ERR) {
184 return false;
185 }
186
187 /* check that the href exists - w3c spec says must be present */
188 exc = dom_element_get_attribute(node, corestring_dom_href, &atr_string);
189 if ((exc != DOM_NO_ERR) || (atr_string == NULL)) {
190 lwc_string_unref(link.rel);
191 return false;
192 }
193
194 /* get nsurl */
195 error = nsurl_join(c->base_url, dom_string_data(atr_string),
196 &link.href);
197 dom_string_unref(atr_string);
198 if (error != NSERROR_OK) {
199 lwc_string_unref(link.rel);
200 return false;
201 }
202
203 /* look for optional properties -- we don't care if internment fails */
204
205 exc = dom_element_get_attribute(node,
206 corestring_dom_hreflang, &atr_string);
207 if ((exc == DOM_NO_ERR) && (atr_string != NULL)) {
208 /* get a lwc string containing the href lang */
209 (void)dom_string_intern(atr_string, &link.hreflang);
210 dom_string_unref(atr_string);
211 }
212
213 exc = dom_element_get_attribute(node,
214 corestring_dom_type, &atr_string);
215 if ((exc == DOM_NO_ERR) && (atr_string != NULL)) {
216 /* get a lwc string containing the type */
217 (void)dom_string_intern(atr_string, &link.type);
218 dom_string_unref(atr_string);
219 }
220
221 exc = dom_element_get_attribute(node,
222 corestring_dom_media, &atr_string);
223 if ((exc == DOM_NO_ERR) && (atr_string != NULL)) {
224 /* get a lwc string containing the media */
225 (void)dom_string_intern(atr_string, &link.media);
226 dom_string_unref(atr_string);
227 }
228
229 exc = dom_element_get_attribute(node,
230 corestring_dom_sizes, &atr_string);
231 if ((exc == DOM_NO_ERR) && (atr_string != NULL)) {
232 /* get a lwc string containing the sizes */
233 (void)dom_string_intern(atr_string, &link.sizes);
234 dom_string_unref(atr_string);
235 }
236
237 /* add to content */
239
240 if (link.sizes != NULL)
241 lwc_string_unref(link.sizes);
242 if (link.media != NULL)
243 lwc_string_unref(link.media);
244 if (link.type != NULL)
245 lwc_string_unref(link.type);
246 if (link.hreflang != NULL)
247 lwc_string_unref(link.hreflang);
248
249 nsurl_unref(link.href);
250 lwc_string_unref(link.rel);
251
252 return true;
253}
254
255
256/* handler for a SCRIPT which has been added to a tree */
257static void
258dom_SCRIPT_showed_up(html_content *htmlc, dom_html_script_element *script)
259{
260 dom_exception exc;
261 dom_html_script_element_flags flags;
262 dom_hubbub_error res;
263 bool within;
264
265 if (!htmlc->enable_scripting) {
266 NSLOG(netsurf, INFO, "Encountered a script, but scripting is off, ignoring");
267 return;
268 }
269
270 NSLOG(netsurf, DEEPDEBUG, "Encountered a script, node %p showed up", script);
271
272 exc = dom_html_script_element_get_flags(script, &flags);
273 if (exc != DOM_NO_ERR) {
274 NSLOG(netsurf, DEEPDEBUG, "Unable to retrieve flags, giving up");
275 return;
276 }
277
278 if (flags & DOM_HTML_SCRIPT_ELEMENT_FLAG_PARSER_INSERTED) {
279 NSLOG(netsurf, DEBUG, "Script was parser inserted, skipping");
280 return;
281 }
282
283 exc = dom_node_contains(htmlc->document, script, &within);
284 if (exc != DOM_NO_ERR) {
285 NSLOG(netsurf, DEBUG, "Unable to determine if script was within document, ignoring");
286 return;
287 }
288
289 if (!within) {
290 NSLOG(netsurf, DEBUG, "Script was not within the document, ignoring for now");
291 return;
292 }
293
294 res = html_process_script(htmlc, (dom_node *) script);
295 if (res == DOM_HUBBUB_OK) {
296 NSLOG(netsurf, DEEPDEBUG, "Inserted script has finished running");
297 } else {
298 if (res == (DOM_HUBBUB_HUBBUB_ERR | HUBBUB_PAUSED)) {
299 NSLOG(netsurf, DEEPDEBUG, "Inserted script has launced asynchronously");
300 } else {
301 NSLOG(netsurf, DEEPDEBUG, "Failure starting script");
302 }
303 }
304}
305
306
307/**
308 * process a META element being inserted into the DOM
309 *
310 * \note only the http-equiv attribute for refresh is currently considered
311 *
312 * \param htmlc The html content containing the DOM
313 * \param n The DOM node being inserted
314 * \return NSERROR_OK on success else appropriate error code
315 */
317{
318 union content_msg_data msg_data;
319 const char *url, *end, *refresh = NULL;
320 char *new_url;
321 char quote = '\0';
322 dom_string *equiv, *content;
323 dom_exception exc;
324 nsurl *nsurl;
325 nserror error = NSERROR_OK;
326
327 if (c->refresh) {
328 /* refresh already delt with */
329 return NSERROR_OK;
330 }
331
332 exc = dom_element_get_attribute(n, corestring_dom_http_equiv, &equiv);
333 if (exc != DOM_NO_ERR) {
334 return NSERROR_DOM;
335 }
336
337 if (equiv == NULL) {
338 return NSERROR_OK;
339 }
340
341 if (!dom_string_caseless_lwc_isequal(equiv, corestring_lwc_refresh)) {
342 dom_string_unref(equiv);
343 return NSERROR_OK;
344 }
345
346 dom_string_unref(equiv);
347
348 exc = dom_element_get_attribute(n, corestring_dom_content, &content);
349 if (exc != DOM_NO_ERR) {
350 return NSERROR_DOM;
351 }
352
353 if (content == NULL) {
354 return NSERROR_OK;
355 }
356
357 end = dom_string_data(content) + dom_string_byte_length(content);
358
359 /* content := *LWS intpart fracpart? *LWS [';' *LWS *1url *LWS]
360 * intpart := 1*DIGIT
361 * fracpart := 1*('.' | DIGIT)
362 * url := "url" *LWS '=' *LWS (url-nq | url-sq | url-dq)
363 * url-nq := *urlchar
364 * url-sq := "'" *(urlchar | '"') "'"
365 * url-dq := '"' *(urlchar | "'") '"'
366 * urlchar := [#x9#x21#x23-#x26#x28-#x7E] | nonascii
367 * nonascii := [#x80-#xD7FF#xE000-#xFFFD#x10000-#x10FFFF]
368 */
369
370 url = dom_string_data(content);
371
372 /* *LWS */
373 while (url < end && ascii_is_space(*url)) {
374 url++;
375 }
376
377 /* intpart */
378 if (url == end || (*url < '0' || '9' < *url)) {
379 /* Empty content, or invalid timeval */
380 dom_string_unref(content);
381 return NSERROR_OK;
382 }
383
384 msg_data.delay = (int) strtol(url, &new_url, 10);
385 /* a very small delay and self-referencing URL can cause a loop
386 * that grinds machines to a halt. To prevent this we set a
387 * minimum refresh delay of 1s. */
388 if (msg_data.delay < 1) {
389 msg_data.delay = 1;
390 }
391
392 url = new_url;
393
394 /* fracpart? (ignored, as delay is integer only) */
395 while (url < end && (('0' <= *url && *url <= '9') ||
396 *url == '.')) {
397 url++;
398 }
399
400 /* *LWS */
401 while (url < end && ascii_is_space(*url)) {
402 url++;
403 }
404
405 /* ';' */
406 if (url < end && *url == ';')
407 url++;
408
409 /* *LWS */
410 while (url < end && ascii_is_space(*url)) {
411 url++;
412 }
413
414 if (url == end) {
415 /* Just delay specified, so refresh current page */
416 dom_string_unref(content);
417
419
421
422 return NSERROR_OK;
423 }
424
425 /* "url" */
426 if (url <= end - 3) {
427 if (strncasecmp(url, "url", 3) == 0) {
428 url += 3;
429 } else {
430 /* Unexpected input, ignore this header */
431 dom_string_unref(content);
432 return NSERROR_OK;
433 }
434 } else {
435 /* Insufficient input, ignore this header */
436 dom_string_unref(content);
437 return NSERROR_OK;
438 }
439
440 /* *LWS */
441 while (url < end && ascii_is_space(*url)) {
442 url++;
443 }
444
445 /* '=' */
446 if (url < end) {
447 if (*url == '=') {
448 url++;
449 } else {
450 /* Unexpected input, ignore this header */
451 dom_string_unref(content);
452 return NSERROR_OK;
453 }
454 } else {
455 /* Insufficient input, ignore this header */
456 dom_string_unref(content);
457 return NSERROR_OK;
458 }
459
460 /* *LWS */
461 while (url < end && ascii_is_space(*url)) {
462 url++;
463 }
464
465 /* '"' or "'" */
466 if (url < end && (*url == '"' || *url == '\'')) {
467 quote = *url;
468 url++;
469 }
470
471 /* Start of URL */
472 refresh = url;
473
474 if (quote != 0) {
475 /* url-sq | url-dq */
476 while (url < end && *url != quote)
477 url++;
478 } else {
479 /* url-nq */
480 while (url < end && !ascii_is_space(*url))
481 url++;
482 }
483
484 /* '"' or "'" or *LWS (we don't care) */
485 if (url > refresh) {
486 /* There's a URL */
487 new_url = strndup(refresh, url - refresh);
488 if (new_url == NULL) {
489 dom_string_unref(content);
490 return NSERROR_NOMEM;
491 }
492
493 error = nsurl_join(c->base_url, new_url, &nsurl);
494 if (error == NSERROR_OK) {
495 /* broadcast valid refresh url */
496
497 c->base.refresh = nsurl;
498
501 &msg_data);
502 c->refresh = true;
503 }
504
505 free(new_url);
506
507 }
508
509 dom_string_unref(content);
510
511 return error;
512}
513
514
515/**
516 * Process title element being inserted into the DOM.
517 *
518 * https://html.spec.whatwg.org/multipage/semantics.html#the-title-element
519 *
520 * \param htmlc The html content containing the DOM
521 * \param node The DOM node being inserted
522 * \return NSERROR_OK on success else appropriate error code
523 */
525{
526 if (htmlc->title == NULL) {
527 /* only the first title is considered */
528 htmlc->title = dom_node_ref(node);
529 }
530 return NSERROR_OK;
531}
532
533
534/** process title node */
535static bool html_process_title(html_content *c, dom_node *node)
536{
537 dom_exception exc; /* returned by libdom functions */
538 dom_string *title;
539 char *title_str;
540 bool success;
541
542 exc = dom_node_get_text_content(node, &title);
543 if ((exc != DOM_NO_ERR) || (title == NULL)) {
544 return false;
545 }
546
547 title_str = squash_whitespace(dom_string_data(title));
548 dom_string_unref(title);
549
550 if (title_str == NULL) {
551 return false;
552 }
553
554 success = content__set_title(&c->base, title_str);
555
556 free(title_str);
557
558 return success;
559}
560
561
562/**
563 * Deal with input elements being modified by resyncing their gadget
564 * if they have one.
565 */
566static void html_texty_element_update(html_content *htmlc, dom_node *node)
567{
568 struct box *box = box_for_node(node);
569 if (box == NULL) {
570 return; /* No Box (yet?) so no gadget to update */
571 }
572 if (box->gadget == NULL) {
573 return; /* No gadget yet (under construction perhaps?) */
574 }
576 /* And schedule a redraw for the box */
577 html__redraw_a_box(htmlc, box);
578}
579
580
581/**
582 * callback for DOMNodeInserted end type
583 */
584static void
585dom_default_action_DOMNodeInserted_cb(struct dom_event *evt, void *pw)
586{
587 dom_event_target *node;
588 dom_node_type type;
589 dom_exception exc;
590 html_content *htmlc = pw;
591
592 exc = dom_event_get_target(evt, &node);
593 if ((exc != DOM_NO_ERR) || (node == NULL)) {
594 /* failed to obtain the event target node */
595 return;
596 }
597
598 exc = dom_node_get_node_type(node, &type);
599 if ((exc == DOM_NO_ERR) && (type == DOM_ELEMENT_NODE)) {
600 /* an element node has been inserted */
601 dom_html_element_type tag_type;
602
603 exc = dom_html_element_get_tag_type(node, &tag_type);
604 if (exc != DOM_NO_ERR) {
605 tag_type = DOM_HTML_ELEMENT_TYPE__UNKNOWN;
606 }
607
608 switch (tag_type) {
609 case DOM_HTML_ELEMENT_TYPE_BASE:
610 html_process_inserted_base(htmlc, (dom_node *)node);
611 break;
612
613 case DOM_HTML_ELEMENT_TYPE_IMG:
614 html_process_inserted_img(htmlc, (dom_node *)node);
615 break;
616
617 case DOM_HTML_ELEMENT_TYPE_LINK:
618 html_process_inserted_link(htmlc, (dom_node *)node);
619 break;
620
621 case DOM_HTML_ELEMENT_TYPE_META:
622 html_process_inserted_meta(htmlc, (dom_node *)node);
623 break;
624
625 case DOM_HTML_ELEMENT_TYPE_STYLE:
626 if (nsoption_bool(author_level_css)) {
627 html_css_process_style(htmlc, (dom_node *)node);
628 }
629 break;
630
631 case DOM_HTML_ELEMENT_TYPE_SCRIPT:
633 (dom_html_script_element *)node);
634 break;
635
636 case DOM_HTML_ELEMENT_TYPE_TITLE:
637 html_process_inserted_title(htmlc, (dom_node *)node);
638 break;
639
640 default:
641 break;
642 }
643
644 if (htmlc->enable_scripting) {
645 /* ensure javascript context is available */
646 if (htmlc->jsthread == NULL) {
647 union content_msg_data msg_data;
648
649 msg_data.jsthread = &htmlc->jsthread;
650 content_broadcast(&htmlc->base,
652 &msg_data);
653 NSLOG(netsurf, INFO,
654 "javascript context: %p (htmlc: %p)",
655 htmlc->jsthread,
656 htmlc);
657 }
658 if (htmlc->jsthread != NULL) {
660 (dom_element *) node);
661 }
662 }
663 }
664 dom_node_unref(node);
665}
666
667
668/**
669 * callback for DOMNodeInsertedIntoDocument end type
670 */
671static void
673 void *pw)
674{
675 html_content *htmlc = pw;
676 dom_event_target *node;
677 dom_node_type type;
678 dom_exception exc;
679
680 exc = dom_event_get_target(evt, &node);
681 if ((exc == DOM_NO_ERR) && (node != NULL)) {
682 exc = dom_node_get_node_type(node, &type);
683 if ((exc == DOM_NO_ERR) && (type == DOM_ELEMENT_NODE)) {
684 /* an element node has been modified */
685 dom_html_element_type tag_type;
686
687 exc = dom_html_element_get_tag_type(node, &tag_type);
688 if (exc != DOM_NO_ERR) {
689 tag_type = DOM_HTML_ELEMENT_TYPE__UNKNOWN;
690 }
691
692 switch (tag_type) {
693 case DOM_HTML_ELEMENT_TYPE_SCRIPT:
694 dom_SCRIPT_showed_up(htmlc, (dom_html_script_element *) node);
696 default:
697 break;
698 }
699 }
700 dom_node_unref(node);
701 }
702}
703
704
705/**
706 * callback for DOMSubtreeModified end type
707 */
708static void
709dom_default_action_DOMSubtreeModified_cb(struct dom_event *evt, void *pw)
710{
711 dom_event_target *node;
712 dom_node_type type;
713 dom_exception exc;
714 html_content *htmlc = pw;
715
716 exc = dom_event_get_target(evt, &node);
717 if ((exc == DOM_NO_ERR) && (node != NULL)) {
718 if (htmlc->title == (dom_node *)node) {
719 /* Node is our title node */
720 html_process_title(htmlc, (dom_node *)node);
721 dom_node_unref(node);
722 return;
723 }
724
725 exc = dom_node_get_node_type(node, &type);
726 if ((exc == DOM_NO_ERR) && (type == DOM_ELEMENT_NODE)) {
727 /* an element node has been modified */
728 dom_html_element_type tag_type;
729
730 exc = dom_html_element_get_tag_type(node, &tag_type);
731 if (exc != DOM_NO_ERR) {
732 tag_type = DOM_HTML_ELEMENT_TYPE__UNKNOWN;
733 }
734
735 switch (tag_type) {
736 case DOM_HTML_ELEMENT_TYPE_STYLE:
737 if (nsoption_bool(author_level_css)) {
739 (dom_node *)node);
740 }
741 break;
742 case DOM_HTML_ELEMENT_TYPE_TEXTAREA:
743 case DOM_HTML_ELEMENT_TYPE_INPUT:
744 html_texty_element_update(htmlc, (dom_node *)node);
746 default:
747 break;
748 }
749 }
750 dom_node_unref(node);
751 }
752}
753
754
755/**
756 * callback for default action finished
757 */
758static void
759dom_default_action_finished_cb(struct dom_event *evt, void *pw)
760{
761 html_content *htmlc = pw;
762
763 if (htmlc->jsthread != NULL)
764 js_event_cleanup(htmlc->jsthread, evt);
765}
766
767
768/* exported interface documented in html/dom_event.c */
769dom_default_action_callback
771 dom_default_action_phase phase,
772 void **pw)
773{
774 NSLOG(netsurf, DEEPDEBUG,
775 "phase:%d type:%s", phase, dom_string_data(type));
776
777 if (phase == DOM_DEFAULT_ACTION_END) {
778 if (dom_string_isequal(type, corestring_dom_DOMNodeInserted)) {
780 } else if (dom_string_isequal(type, corestring_dom_DOMNodeInsertedIntoDocument)) {
782 } else if (dom_string_isequal(type, corestring_dom_DOMSubtreeModified)) {
784 }
785 } else if (phase == DOM_DEFAULT_ACTION_FINISHED) {
787 }
788 return NULL;
789}
Helpers for ASCII string handling.
static bool ascii_is_space(char c)
Test whether a character is a whitespace character.
Definition: ascii.h:40
Box interface.
struct box * box_for_node(dom_node *n)
Retrieve the box for a dom node, if there is one.
HTML Box tree construction interface.
char * strndup(const char *s, size_t n)
Duplicate up to n characters of a string.
Definition: utils.c:332
Content handling interface.
HTML content handler CSS interface.
bool html_fetch_object(html_content *c, nsurl *url, struct box *box, content_type permitted_types, bool background)
Start a fetch for an object required by a page.
Definition: object.c:710
HTML content object interface.
bool content__add_rfc5988_link(struct content *c, const struct content_rfc5988_link *link)
associate a metadata link with a content.
Definition: content.c:1001
void content_broadcast(struct content *c, content_msg msg, const union content_msg_data *data)
Send a message to all users.
Definition: content.c:752
bool content__set_title(struct content *c, const char *title)
Set title associated with content.
Definition: content.c:1090
nsurl * content_get_url(struct content *c)
Retrieve URL associated with content.
Definition: content.c:1051
@ CONTENT_IMAGE
All images.
Definition: content_type.h:67
@ CONTENT_MSG_REFRESH
wants refresh
Definition: content_type.h:137
@ CONTENT_MSG_GETTHREAD
Javascript thread.
Definition: content_type.h:146
Useful interned string pointers (interface).
static nserror html_process_inserted_title(html_content *htmlc, dom_node *node)
Process title element being inserted into the DOM.
Definition: dom_event.c:524
static void dom_default_action_DOMSubtreeModified_cb(struct dom_event *evt, void *pw)
callback for DOMSubtreeModified end type
Definition: dom_event.c:709
static void dom_default_action_DOMNodeInserted_cb(struct dom_event *evt, void *pw)
callback for DOMNodeInserted end type
Definition: dom_event.c:585
static void dom_SCRIPT_showed_up(html_content *htmlc, dom_html_script_element *script)
Definition: dom_event.c:258
static void dom_default_action_finished_cb(struct dom_event *evt, void *pw)
callback for default action finished
Definition: dom_event.c:759
static bool html_process_title(html_content *c, dom_node *node)
process title node
Definition: dom_event.c:535
static void dom_default_action_DOMNodeInsertedIntoDocument_cb(struct dom_event *evt, void *pw)
callback for DOMNodeInsertedIntoDocument end type
Definition: dom_event.c:672
dom_default_action_callback html_dom_event_fetcher(dom_string *type, dom_default_action_phase phase, void **pw)
html content DOM action callback function selector
Definition: dom_event.c:770
static bool html_process_inserted_img(html_content *htmlc, dom_node *node)
Process img element being inserted into the DOM.
Definition: dom_event.c:119
static bool html_process_inserted_base(html_content *htmlc, dom_node *node)
process a base element being inserted into the DOM
Definition: dom_event.c:56
static bool html_process_inserted_link(html_content *c, dom_node *node)
process a LINK element being inserted into the DOM
Definition: dom_event.c:161
static void html_texty_element_update(html_content *htmlc, dom_node *node)
Deal with input elements being modified by resyncing their gadget if they have one.
Definition: dom_event.c:566
static nserror html_process_inserted_meta(html_content *c, dom_node *n)
process a META element being inserted into the DOM
Definition: dom_event.c:316
HTML content DOM event handling interface.
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_DOM
DOM call returned error.
Definition: errors.h:52
@ NSERROR_NOMEM
Memory exhaustion.
Definition: errors.h:32
@ NSERROR_OK
No error.
Definition: errors.h:30
const char * type
Definition: filetype.cpp:44
void form_gadget_sync_with_dom(struct form_control *control)
Synchronise this gadget with its associated DOM node.
Definition: form.c:2170
Interface to form handling functions internal to HTML content handler.
bool html_css_process_style(html_content *c, dom_node *node)
process a css style dom node
Definition: css.c:352
bool html_css_process_link(html_content *htmlc, dom_node *node)
process a css stylesheet dom LINK node
Definition: css.c:385
bool html_css_update_style(html_content *c, dom_node *style)
process a css style dom node update
Definition: css.c:323
void html__redraw_a_box(struct html_content *html, struct box *box)
Redraw a box.
Definition: html.c:1130
Generic bitmap handling interface.
Interface to javascript engine functions.
void js_handle_new_element(jsthread *thread, struct dom_element *node)
Handle a new element being created.
Definition: dukky.c:1471
void js_event_cleanup(jsthread *thread, struct dom_event *evt)
Handle an event propagation finished callback.
Definition: dukky.c:1551
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:116
NetSurf URL handling (interface).
nserror nsurl_create(const char *const url_s, nsurl **url)
Create a NetSurf URL object from a URL string.
void nsurl_unref(nsurl *url)
Drop a reference to a NetSurf URL object.
nsurl * nsurl_ref(nsurl *url)
Increment the reference count to a NetSurf URL object.
nserror nsurl_join(const nsurl *base, const char *rel, nsurl **joined)
Join a base url to a relative link part, creating a new NetSurf URL object.
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
Private data for text/html content.
dom_hubbub_error html_process_script(void *ctx, dom_node *node)
process script node parser callback
Definition: script.c:566
Interface to utility string handling.
char * squash_whitespace(const char *s)
Replace consecutive whitespace with a single space.
Definition: utils.c:38
Node in box tree.
Definition: box.h:177
struct form_control * gadget
Form control data, or NULL if not a form control.
Definition: box.h:423
struct dom_node * node
DOM node that generated this box or NULL.
Definition: box.h:191
Content which corresponds to a single URL.
struct nsurl * refresh
URL for refresh request.
Data specific to CONTENT_HTML.
Definition: private.h:93
bool refresh
Whether a meta refresh has been handled.
Definition: private.h:119
dom_document * document
Document tree.
Definition: private.h:101
struct nsurl * base_url
Base URL (may be a copy of content->url).
Definition: private.h:111
char * base_target
Base target.
Definition: private.h:113
struct jsthread * jsthread
javascript thread in use
Definition: private.h:152
bool enable_scripting
Whether scripts are enabled for this content.
Definition: private.h:128
struct content base
Definition: private.h:94
dom_node * title
Definition: private.h:131
Extra data for some content_msg messages.
Definition: content.h:60
int delay
CONTENT_MSG_REFRESH - Minimum delay.
Definition: content.h:116
const char * title
Definition: content.h:186
struct jsthread ** jsthread
CONTENT_MSG_GETTHREAD - Javascript context (thread)
Definition: content.h:143
struct hlcache_handle * content
if NULL, save the content generating the message
Definition: content.h:178
struct nsurl * url
Definition: content.h:185
Option reading and saving interface.
#define nsoption_bool(OPTION)
Get the value of a boolean option.
Definition: nsoption.h:304
Interface to a number of general purpose functionality.
#define fallthrough
switch fall through
Definition: utils.h:119