NetSurf
html_script.c
Go to the documentation of this file.
1 /*
2  * Copyright 2012 Vincent Sanders <vince@netsurf-browser.org>
3  *
4  * This file is part of NetSurf, http://www.netsurf-browser.org/
5  *
6  * NetSurf is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * NetSurf is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 /**
20  * \file
21  * implementation of content handling for text/html scripts.
22  */
23 
24 #include <assert.h>
25 #include <ctype.h>
26 #include <stdint.h>
27 #include <stdbool.h>
28 #include <string.h>
29 #include <strings.h>
30 #include <stdlib.h>
31 
32 #include "utils/config.h"
33 #include "utils/corestrings.h"
34 #include "utils/log.h"
35 #include "utils/messages.h"
36 #include "netsurf/content.h"
37 #include "javascript/js.h"
39 #include "content/fetch.h"
40 #include "content/hlcache.h"
41 
42 #include "html/html.h"
43 #include "html/html_internal.h"
44 
45 typedef bool (script_handler_t)(struct jsthread *jsthread, const uint8_t *data, size_t size, const char *name);
46 
47 
49 {
50  if (ctype == CONTENT_JS) {
51  return js_exec;
52  }
53  return NULL;
54 }
55 
56 
57 /* exported internal interface documented in html/html_internal.h */
58 nserror html_script_exec(html_content *c, bool allow_defer)
59 {
60  unsigned int i;
61  struct html_script *s;
62  script_handler_t *script_handler;
63  bool have_run_something = false;
64 
65  if (c->jsthread == NULL) {
66  return NSERROR_BAD_PARAMETER;
67  }
68 
69  for (i = 0, s = c->scripts; i != c->scripts_count; i++, s++) {
70  if (s->already_started) {
71  continue;
72  }
73 
74  if ((s->type == HTML_SCRIPT_ASYNC) ||
75  (allow_defer && (s->type == HTML_SCRIPT_DEFER))) {
76  /* ensure script content is present */
77  if (s->data.handle == NULL)
78  continue;
79 
80  /* ensure script content fetch status is not an error */
81  if (content_get_status(s->data.handle) ==
83  continue;
84 
85  /* ensure script handler for content type */
86  script_handler = select_script_handler(
88  if (script_handler == NULL)
89  continue; /* unsupported type */
90 
91  if (content_get_status(s->data.handle) ==
93  /* external script is now available */
94  const uint8_t *data;
95  size_t size;
97  s->data.handle, &size );
98  script_handler(c->jsthread, data, size,
100  have_run_something = true;
101  /* We have to re-acquire this here since the
102  * c->scripts array may have been reallocated
103  * as a result of executing this script.
104  */
105  s = &(c->scripts[i]);
106 
107  s->already_started = true;
108 
109  }
110  }
111  }
112 
113  if (have_run_something) {
114  return html_proceed_to_done(c);
115  }
116 
117  return NSERROR_OK;
118 }
119 
120 /* create new html script entry */
121 static struct html_script *
123  dom_string *mimetype,
124  enum html_script_type type)
125 {
126  struct html_script *nscript;
127  /* add space for new script entry */
128  nscript = realloc(c->scripts,
129  sizeof(struct html_script) * (c->scripts_count + 1));
130  if (nscript == NULL) {
131  return NULL;
132  }
133 
134  c->scripts = nscript;
135 
136  /* increment script entry count */
137  nscript = &c->scripts[c->scripts_count];
138  c->scripts_count++;
139 
140  nscript->already_started = false;
141  nscript->parser_inserted = false;
142  nscript->force_async = true;
143  nscript->ready_exec = false;
144  nscript->async = false;
145  nscript->defer = false;
146 
147  nscript->type = type;
148 
149  nscript->mimetype = dom_string_ref(mimetype); /* reference mimetype */
150 
151  return nscript;
152 }
153 
154 /**
155  * Callback for asyncronous scripts
156  */
157 static nserror
159  const hlcache_event *event,
160  void *pw)
161 {
162  html_content *parent = pw;
163  unsigned int i;
164  struct html_script *s;
165 
166  /* Find script */
167  for (i = 0, s = parent->scripts; i != parent->scripts_count; i++, s++) {
168  if (s->type == HTML_SCRIPT_ASYNC && s->data.handle == script)
169  break;
170  }
171 
172  assert(i != parent->scripts_count);
173 
174  switch (event->type) {
175  case CONTENT_MSG_LOADING:
176  break;
177 
178  case CONTENT_MSG_READY:
179  break;
180 
181  case CONTENT_MSG_DONE:
182  NSLOG(netsurf, INFO, "script %d done '%s'", i,
184  parent->base.active--;
185  NSLOG(netsurf, INFO, "%d fetches active", parent->base.active);
186 
187  break;
188 
189  case CONTENT_MSG_ERROR:
190  NSLOG(netsurf, INFO, "script %s failed: %s",
192  event->data.errordata.errormsg);
193 
194  hlcache_handle_release(script);
195  s->data.handle = NULL;
196  parent->base.active--;
197  NSLOG(netsurf, INFO, "%d fetches active", parent->base.active);
198  content_add_error(&parent->base, "?", 0);
199 
200  break;
201 
202  default:
203  break;
204  }
205 
206  /* if there are no active fetches remaining begin post parse
207  * conversion
208  */
209  if (html_can_begin_conversion(parent)) {
210  html_begin_conversion(parent);
211  }
212 
213  /* if we have already started converting though, then we can handle the
214  * scripts as they come in.
215  */
216  else if (parent->conversion_begun) {
217  return html_script_exec(parent, false);
218  }
219 
220  return NSERROR_OK;
221 }
222 
223 /**
224  * Callback for defer scripts
225  */
226 static nserror
228  const hlcache_event *event,
229  void *pw)
230 {
231  html_content *parent = pw;
232  unsigned int i;
233  struct html_script *s;
234 
235  /* Find script */
236  for (i = 0, s = parent->scripts; i != parent->scripts_count; i++, s++) {
237  if (s->type == HTML_SCRIPT_DEFER && s->data.handle == script)
238  break;
239  }
240 
241  assert(i != parent->scripts_count);
242 
243  switch (event->type) {
244 
245  case CONTENT_MSG_DONE:
246  NSLOG(netsurf, INFO, "script %d done '%s'", i,
248  parent->base.active--;
249  NSLOG(netsurf, INFO, "%d fetches active", parent->base.active);
250 
251  break;
252 
253  case CONTENT_MSG_ERROR:
254  NSLOG(netsurf, INFO, "script %s failed: %s",
256  event->data.errordata.errormsg);
257 
258  hlcache_handle_release(script);
259  s->data.handle = NULL;
260  parent->base.active--;
261  NSLOG(netsurf, INFO, "%d fetches active", parent->base.active);
262  content_add_error(&parent->base, "?", 0);
263 
264  break;
265 
266  default:
267  break;
268  }
269 
270  /* if there are no active fetches remaining begin post parse
271  * conversion
272  */
273  if (html_can_begin_conversion(parent)) {
274  html_begin_conversion(parent);
275  }
276 
277  return NSERROR_OK;
278 }
279 
280 /**
281  * Callback for syncronous scripts
282  */
283 static nserror
285  const hlcache_event *event,
286  void *pw)
287 {
288  html_content *parent = pw;
289  unsigned int i;
290  struct html_script *s;
291  script_handler_t *script_handler;
292  dom_hubbub_error err;
293  unsigned int active_sync_scripts = 0;
294 
295  /* Count sync scripts which have yet to complete (other than us) */
296  for (i = 0, s = parent->scripts; i != parent->scripts_count; i++, s++) {
297  if (s->type == HTML_SCRIPT_SYNC &&
298  s->data.handle != script && s->already_started == false) {
299  active_sync_scripts++;
300  }
301  }
302 
303  /* Find script */
304  for (i = 0, s = parent->scripts; i != parent->scripts_count; i++, s++) {
305  if (s->type == HTML_SCRIPT_SYNC && s->data.handle == script)
306  break;
307  }
308 
309  assert(i != parent->scripts_count);
310 
311  switch (event->type) {
312  case CONTENT_MSG_DONE:
313  NSLOG(netsurf, INFO, "script %d done '%s'", i,
315  parent->base.active--;
316  NSLOG(netsurf, INFO, "%d fetches active", parent->base.active);
317 
318  s->already_started = true;
319 
320  /* attempt to execute script */
321  script_handler = select_script_handler(content_get_type(s->data.handle));
322  if (script_handler != NULL && parent->jsthread != NULL) {
323  /* script has a handler */
324  const uint8_t *data;
325  size_t size;
326  data = content_get_source_data(s->data.handle, &size );
327  script_handler(parent->jsthread, data, size,
329  }
330 
331  /* continue parse */
332  if (parent->parser != NULL && active_sync_scripts == 0) {
333  err = dom_hubbub_parser_pause(parent->parser, false);
334  if (err != DOM_HUBBUB_OK) {
335  NSLOG(netsurf, INFO, "unpause returned 0x%x", err);
336  }
337  }
338 
339  break;
340 
341  case CONTENT_MSG_ERROR:
342  NSLOG(netsurf, INFO, "script %s failed: %s",
344  event->data.errordata.errormsg);
345 
346  hlcache_handle_release(script);
347  s->data.handle = NULL;
348  parent->base.active--;
349 
350  NSLOG(netsurf, INFO, "%d fetches active", parent->base.active);
351  content_add_error(&parent->base, "?", 0);
352 
353  s->already_started = true;
354 
355  /* continue parse */
356  if (parent->parser != NULL && active_sync_scripts == 0) {
357  err = dom_hubbub_parser_pause(parent->parser, false);
358  if (err != DOM_HUBBUB_OK) {
359  NSLOG(netsurf, INFO, "unpause returned 0x%x", err);
360  }
361  }
362 
363  break;
364 
365  default:
366  break;
367  }
368 
369  /* if there are no active fetches remaining begin post parse
370  * conversion
371  */
372  if (html_can_begin_conversion(parent)) {
373  html_begin_conversion(parent);
374  }
375 
376  return NSERROR_OK;
377 }
378 
379 /**
380  * process a script with a src tag
381  */
382 static dom_hubbub_error
384  dom_node *node,
385  dom_string *mimetype,
386  dom_string *src)
387 {
388  nserror ns_error;
389  nsurl *joined;
390  hlcache_child_context child;
391  struct html_script *nscript;
392  bool async;
393  bool defer;
394  enum html_script_type script_type;
395  hlcache_handle_callback script_cb;
396  dom_hubbub_error ret = DOM_HUBBUB_OK;
397  dom_exception exc; /* returned by libdom functions */
398 
399  /* src url */
400  ns_error = nsurl_join(c->base_url, dom_string_data(src), &joined);
401  if (ns_error != NSERROR_OK) {
403  return DOM_HUBBUB_NOMEM;
404  }
405 
406  NSLOG(netsurf, INFO, "script %i '%s'", c->scripts_count,
407  nsurl_access(joined));
408 
409  /* there are three ways to process the script tag at this point:
410  *
411  * Syncronously pause the parent parse and continue after
412  * the script has downloaded and executed. (default)
413  * Async Start the script downloading and execute it when it
414  * becomes available.
415  * Defered Start the script downloading and execute it when
416  * the page has completed parsing, may be set along
417  * with async where it is ignored.
418  */
419 
420  /* we interpret the presence of the async and defer attribute
421  * as true and ignore its value, technically only the empty
422  * value or the attribute name itself are valid. However
423  * various browsers interpret this in various ways the most
424  * compatible approach is to be liberal and accept any
425  * value. Note setting the values to "false" still makes them true!
426  */
427  exc = dom_element_has_attribute(node, corestring_dom_async, &async);
428  if (exc != DOM_NO_ERR) {
429  return DOM_HUBBUB_OK; /* dom error */
430  }
431 
432  if (c->parse_completed) {
433  /* After parse completed, all scripts are essentially async */
434  async = true;
435  defer = false;
436  }
437 
438  if (async) {
439  /* asyncronous script */
440  script_type = HTML_SCRIPT_ASYNC;
441  script_cb = convert_script_async_cb;
442 
443  } else {
444  exc = dom_element_has_attribute(node,
445  corestring_dom_defer, &defer);
446  if (exc != DOM_NO_ERR) {
447  return DOM_HUBBUB_OK; /* dom error */
448  }
449 
450  if (defer) {
451  /* defered script */
452  script_type = HTML_SCRIPT_DEFER;
453  script_cb = convert_script_defer_cb;
454  } else {
455  /* syncronous script */
456  script_type = HTML_SCRIPT_SYNC;
457  script_cb = convert_script_sync_cb;
458  }
459  }
460 
461  nscript = html_process_new_script(c, mimetype, script_type);
462  if (nscript == NULL) {
463  nsurl_unref(joined);
465  return DOM_HUBBUB_NOMEM;
466  }
467 
468  /* set up child fetch encoding and quirks */
469  child.charset = c->encoding;
470  child.quirks = c->base.quirks;
471 
472  ns_error = hlcache_handle_retrieve(joined,
473  0,
474  content_get_url(&c->base),
475  NULL,
476  script_cb,
477  c,
478  &child,
480  &nscript->data.handle);
481 
482 
483  nsurl_unref(joined);
484 
485  if (ns_error != NSERROR_OK) {
486  /* @todo Deal with fetch error better. currently assume
487  * fetch never became active
488  */
489  /* mark duff script fetch as already started */
490  nscript->already_started = true;
491  NSLOG(netsurf, INFO, "Fetch failed with error %d", ns_error);
492  } else {
493  /* update base content active fetch count */
494  c->base.active++;
495  NSLOG(netsurf, INFO, "%d fetches active", c->base.active);
496 
497  switch (script_type) {
498  case HTML_SCRIPT_SYNC:
499  ret = DOM_HUBBUB_HUBBUB_ERR | HUBBUB_PAUSED;
500 
501  case HTML_SCRIPT_ASYNC:
502  break;
503 
504  case HTML_SCRIPT_DEFER:
505  break;
506 
507  default:
508  assert(0);
509  }
510  }
511 
512  return ret;
513 }
514 
515 static dom_hubbub_error
516 exec_inline_script(html_content *c, dom_node *node, dom_string *mimetype)
517 {
518  dom_string *script;
519  dom_exception exc; /* returned by libdom functions */
520  struct lwc_string_s *lwcmimetype;
521  script_handler_t *script_handler;
522  struct html_script *nscript;
523 
524  /* does not appear to be a src so script is inline content */
525  exc = dom_node_get_text_content(node, &script);
526  if ((exc != DOM_NO_ERR) || (script == NULL)) {
527  return DOM_HUBBUB_OK; /* no contents, skip */
528  }
529 
530  nscript = html_process_new_script(c, mimetype, HTML_SCRIPT_INLINE);
531  if (nscript == NULL) {
532  dom_string_unref(script);
533 
535  return DOM_HUBBUB_NOMEM;
536 
537  }
538 
539  nscript->data.string = script;
540  nscript->already_started = true;
541 
542  /* ensure script handler for content type */
543  exc = dom_string_intern(mimetype, &lwcmimetype);
544  if (exc != DOM_NO_ERR) {
545  return DOM_HUBBUB_DOM;
546  }
547 
548  script_handler = select_script_handler(content_factory_type_from_mime_type(lwcmimetype));
549  lwc_string_unref(lwcmimetype);
550 
551  if (script_handler != NULL) {
552  script_handler(c->jsthread,
553  (const uint8_t *)dom_string_data(script),
554  dom_string_byte_length(script),
555  "?inline script?");
556  }
557  return DOM_HUBBUB_OK;
558 }
559 
560 
561 /**
562  * process script node parser callback
563  *
564  *
565  */
566 dom_hubbub_error
567 html_process_script(void *ctx, dom_node *node)
568 {
569  html_content *c = (html_content *)ctx;
570  dom_exception exc; /* returned by libdom functions */
571  dom_string *src, *mimetype;
572  dom_hubbub_error err = DOM_HUBBUB_OK;
573 
574  /* ensure javascript context is available */
575  /* We should only ever be here if scripting was enabled for this
576  * content so it's correct to make a javascript context if there
577  * isn't one already. */
578  if (c->jsthread == NULL) {
579  union content_msg_data msg_data;
580 
581  msg_data.jsthread = &c->jsthread;
583  NSLOG(netsurf, INFO, "javascript context %p ", c->jsthread);
584  if (c->jsthread == NULL) {
585  /* no context and it could not be created, abort */
586  return DOM_HUBBUB_OK;
587  }
588  }
589 
590  NSLOG(netsurf, INFO, "content %p parser %p node %p", c, c->parser,
591  node);
592 
593  exc = dom_element_get_attribute(node, corestring_dom_type, &mimetype);
594  if (exc != DOM_NO_ERR || mimetype == NULL) {
595  mimetype = dom_string_ref(corestring_dom_text_javascript);
596  }
597 
598  exc = dom_element_get_attribute(node, corestring_dom_src, &src);
599  if (exc != DOM_NO_ERR || src == NULL) {
600  err = exec_inline_script(c, node, mimetype);
601  } else {
602  err = exec_src_script(c, node, mimetype, src);
603  dom_string_unref(src);
604  }
605 
606  dom_string_unref(mimetype);
607 
608  return err;
609 }
610 
611 /* exported internal interface documented in html/html_internal.h */
613 {
614  struct html_script *s;
615  unsigned int i;
616 
617  for (i = 0, s = htmlc->scripts; i != htmlc->scripts_count; i++, s++) {
618  if (s->type == HTML_SCRIPT_INLINE) {
619  /* Inline scripts are no less secure than their
620  * containing HTML content
621  */
622  continue;
623  }
624  if (s->data.handle == NULL) {
625  /* We've not begun loading this? */
626  continue;
627  }
629  return true;
630  }
631  }
632 
633  return false;
634 }
635 
636 /* exported internal interface documented in html/html_internal.h */
638 {
639  unsigned int i;
640 
641  for (i = 0; i != html->scripts_count; i++) {
642  if (html->scripts[i].mimetype != NULL) {
643  dom_string_unref(html->scripts[i].mimetype);
644  }
645 
646  switch (html->scripts[i].type) {
647  case HTML_SCRIPT_INLINE:
648  if (html->scripts[i].data.string != NULL) {
649  dom_string_unref(html->scripts[i].data.string);
650  }
651  break;
652  case HTML_SCRIPT_SYNC:
653  /* fallthrough */
654  case HTML_SCRIPT_ASYNC:
655  /* fallthrough */
656  case HTML_SCRIPT_DEFER:
657  if (html->scripts[i].data.handle != NULL) {
659  }
660  break;
661  }
662  }
663  free(html->scripts);
664 
665  return NSERROR_OK;
666 }
bool quirks
Whether parent is quirky.
Definition: hlcache.h:39
fetching or converting
Definition: content.h:64
High-level cache event.
Definition: hlcache.h:43
struct content base
Definition: html_internal.h:94
static script_handler_t * select_script_handler(content_type ctype)
Definition: html_script.c:48
struct content_msg_data::@104 errordata
CONTENT_MSG_ERROR - Error from content or underlying fetch.
Interface to utility string handling.
union content_msg_data data
Event data.
Definition: hlcache.h:45
enum html_script::html_script_type type
Localised message support (interface).
content_msg type
Event type.
Definition: hlcache.h:44
Public content interface.
nserror html_proceed_to_done(html_content *html)
Complete the HTML content state machine iff all scripts are finished.
Definition: html.c:280
bool async
Definition: html.h:85
bool js_exec(jsthread *thread, const uint8_t *txt, size_t txtlen, const char *name)
execute some javascript in a context
Definition: dukky.c:919
Interface to text/html content handler.
bool force_async
Definition: html.h:83
Memory exhaustion.
Definition: errors.h:32
bool quirks
Content is in quirks mode.
Context for retrieving a child object.
Definition: hlcache.h:37
bool html_begin_conversion(html_content *htmlc)
Begin conversion of an HTML document.
Definition: html.c:1460
bool conversion_begun
Whether or not the conversion has begun.
Definition: html_internal.h:98
may be displayed
Definition: content.h:65
struct jsthread ** jsthread
CONTENT_MSG_GETTHREAD - Javascript context (thread)
Definition: content.h:185
bool defer
Definition: html.h:86
struct jsthread * jsthread
javascript thread in use
void content_broadcast_error(struct content *c, nserror errorcode, const char *msg)
Send an error message to all users.
Definition: content.c:859
High-level resource cache interface.
Javascript thread.
Definition: content.h:75
Error occurred, content will be destroyed imminently.
Definition: content.h:56
const char * type
Definition: filetype.cpp:44
nserror html_script_free(html_content *html)
Free all script resources and references for a html content.
Definition: html_script.c:637
struct dom_string * string
Definition: html.h:77
nserror
Enumeration of error codes.
Definition: errors.h:29
nsurl * content_get_url(struct content *c)
Retrieve URL associated with content.
Definition: content.c:1172
struct jsthread jsthread
JavaScript interpreter thread.
Definition: js.h:53
High-level cache handle.
Definition: hlcache.c:64
struct dom_string * mimetype
Definition: html.h:79
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.
Useful interned string pointers (interface).
Private data for text/html content.
content_type
The type of a content.
Definition: content_type.h:43
nserror html_script_exec(html_content *c, bool allow_defer)
Attempt script execution for defer and async scripts.
Definition: html_script.c:58
const char * charset
Charset of parent.
Definition: hlcache.h:38
No error.
Definition: errors.h:30
All finished.
Definition: content.h:55
static nserror convert_script_defer_cb(hlcache_handle *script, const hlcache_event *event, void *pw)
Callback for defer scripts.
Definition: html_script.c:227
union html_script::@137 data
Script data.
#define NSLOG(catname, level, logmsg, args...)
Definition: log.h:115
const uint8_t * content_get_source_data(struct hlcache_handle *h, size_t *size)
Retrieve source of content.
Definition: content.c:1323
const char * errormsg
The message.
Definition: content.h:137
struct nsurl * hlcache_handle_get_url(const struct hlcache_handle *handle)
Retrieve the URL associated with a high level cache handle.
unsigned int active
Number of child fetches or conversions currently in progress.
struct hlcache_handle * handle
Definition: html.h:76
content_status content_get_status(hlcache_handle *h)
Retrieve status of content.
Definition: content.c:1243
bool content_saw_insecure_objects(struct hlcache_handle *h)
Determine if the content referred to any insecure objects.
Definition: content.c:569
wimp_w parent
Definition: dialog.c:87
bool() script_handler_t(struct jsthread *jsthread, const uint8_t *data, size_t size, const char *name)
Definition: html_script.c:45
dom_hubbub_error html_process_script(void *ctx, dom_node *node)
process script node parser callback
Definition: html_script.c:567
Bad Parameter.
Definition: errors.h:48
finished
Definition: content.h:66
Interface to javascript engine functions.
static dom_hubbub_error exec_inline_script(html_content *c, dom_node *node, dom_string *mimetype)
Definition: html_script.c:516
static nserror convert_script_async_cb(hlcache_handle *script, const hlcache_event *event, void *pw)
Callback for asyncronous scripts.
Definition: html_script.c:158
void content_broadcast(struct content *c, content_msg msg, const union content_msg_data *data)
Send a message to all users.
Definition: content.c:844
nserror(* hlcache_handle_callback)(hlcache_handle *handle, const hlcache_event *event, void *pw)
Client callback for high-level cache events.
Definition: hlcache.h:63
bool parser_inserted
Definition: html.h:82
error occurred
Definition: content.h:67
dukky javascript thread
Definition: dukky.c:70
dom_hubbub_parser * parser
Parser object handle.
Definition: html_internal.h:96
html_script_type
Type of script.
Definition: html.h:71
All script types.
Definition: content_type.h:69
nsurl * base_url
Base URL (may be a copy of content->url).
content_type content_factory_type_from_mime_type(lwc_string *mime_type)
Compute the generic content type for a MIME type.
content_type content_get_type(struct hlcache_handle *h)
Retrieve computed type of content.
Definition: content.c:1182
struct html_script * scripts
Scripts.
nserror hlcache_handle_retrieve(nsurl *url, uint32_t flags, nsurl *referer, llcache_post_data *post, hlcache_handle_callback cb, void *pw, hlcache_child_context *child, content_type accepted_types, hlcache_handle **result)
Retrieve a high-level cache handle for an object.
Definition: hlcache.c:675
const char * nsurl_access(const nsurl *url)
Access a NetSurf URL object as a string.
Fetching of data from a URL (interface).
bool html_saw_insecure_scripts(html_content *htmlc)
Check if any of the scripts loaded were insecure.
Definition: html_script.c:612
char * encoding
Encoding of source, NULL if unknown.
static nserror convert_script_sync_cb(hlcache_handle *script, const hlcache_event *event, void *pw)
Callback for syncronous scripts.
Definition: html_script.c:284
bool ready_exec
Definition: html.h:84
void content_add_error(struct content *c, const char *token, unsigned int line)
Definition: content.c:1071
static struct html_script * html_process_new_script(html_content *c, dom_string *mimetype, enum html_script_type type)
Definition: html_script.c:122
Javascript.
Definition: content_type.h:66
Data specific to CONTENT_HTML.
Definition: html_internal.h:93
static dom_hubbub_error exec_src_script(html_content *c, dom_node *node, dom_string *mimetype, dom_string *src)
process a script with a src tag
Definition: html_script.c:383
unsigned int scripts_count
Number of entries in scripts.
nserror hlcache_handle_release(hlcache_handle *handle)
Release a high-level cache handle.
Definition: hlcache.c:733
Container for scripts used by an HTML document.
Definition: html.h:69
bool already_started
Definition: html.h:81
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
Protected interface to Content handling.
bool html_can_begin_conversion(html_content *htmlc)
Test if an HTML content conversion can begin.
Definition: html.c:1441
Extra data for some content_msg messages.
Definition: content.h:102
bool parse_completed
Whether the parse has been completed.
Definition: html_internal.h:97
void nsurl_unref(nsurl *url)
Drop a reference to a NetSurf URL object.