Gitweb links:

...log 
http://git.netsurf-browser.org/netsurf.git/shortlog/19b45fb494358838be8b3175fde9e3ab55ef5bfa
...commit 
http://git.netsurf-browser.org/netsurf.git/commit/19b45fb494358838be8b3175fde9e3ab55ef5bfa
...tree 
http://git.netsurf-browser.org/netsurf.git/tree/19b45fb494358838be8b3175fde9e3ab55ef5bfa

The branch, master has been updated
       via  19b45fb494358838be8b3175fde9e3ab55ef5bfa (commit)
      from  90cabaf8c88782a07cd8bdc448bd21e471eeb072 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commitdiff 
http://git.netsurf-browser.org/netsurf.git/commit/?id=19b45fb494358838be8b3175fde9e3ab55ef5bfa
commit 19b45fb494358838be8b3175fde9e3ab55ef5bfa
Author: Daniel Silverstone <[email protected]>
Commit: Daniel Silverstone <[email protected]>

    Support script insertion after conversion has begun
    
    Signed-off-by: Daniel Silverstone <[email protected]>

diff --git a/content/handlers/html/html.c b/content/handlers/html/html.c
index 62f625f..30af90f 100644
--- a/content/handlers/html/html.c
+++ b/content/handlers/html/html.c
@@ -645,6 +645,56 @@ void html_finish_conversion(html_content *htmlc)
        dom_node_unref(html);
 }
 
+/* handler for a SCRIPT which has been added to a tree */
+static void
+dom_SCRIPT_showed_up(html_content *htmlc, dom_html_script_element *script)
+{
+       dom_exception exc;
+       dom_html_script_element_flags flags;
+       dom_hubbub_error res;
+       bool within;
+
+       if (!htmlc->enable_scripting) {
+               NSLOG(netsurf, INFO, "Encountered a script, but scripting is 
off, ignoring");
+               return;
+       }
+
+       NSLOG(netsurf, DEEPDEBUG, "Encountered a script, node %p showed up", 
script);
+
+       exc = dom_html_script_element_get_flags(script, &flags);
+       if (exc != DOM_NO_ERR) {
+               NSLOG(netsurf, DEEPDEBUG, "Unable to retrieve flags, giving 
up");
+               return;
+       }
+
+       if (flags & DOM_HTML_SCRIPT_ELEMENT_FLAG_PARSER_INSERTED) {
+               NSLOG(netsurf, DEBUG, "Script was parser inserted, skipping");
+               return;
+       }
+
+       exc = dom_node_contains(htmlc->document, script, &within);
+       if (exc != DOM_NO_ERR) {
+               NSLOG(netsurf, DEBUG, "Unable to determine if script was within 
document, ignoring");
+               return;
+       }
+
+       if (!within) {
+               NSLOG(netsurf, DEBUG, "Script was not within the document, 
ignoring for now");
+               return;
+       }
+
+       res = html_process_script(htmlc, (dom_node *) script);
+       if (res == DOM_HUBBUB_OK) {
+               NSLOG(netsurf, DEEPDEBUG, "Inserted script has finished 
running");
+       } else {
+               if (res == (DOM_HUBBUB_HUBBUB_ERR | HUBBUB_PAUSED)) {
+                       NSLOG(netsurf, DEEPDEBUG, "Inserted script has launced 
asynchronously");
+               } else {
+                       NSLOG(netsurf, DEEPDEBUG, "Failure starting script");
+               }
+       }
+}
+
 /* callback for DOMNodeInserted end type */
 static void
 dom_default_action_DOMNodeInserted_cb(struct dom_event *evt, void *pw)
@@ -693,6 +743,9 @@ dom_default_action_DOMNodeInserted_cb(struct dom_event 
*evt, void *pw)
                        case DOM_HTML_ELEMENT_TYPE_STYLE:
                                html_css_process_style(htmlc, (dom_node *) 
node);
                                break;
+                       case DOM_HTML_ELEMENT_TYPE_SCRIPT:
+                               dom_SCRIPT_showed_up(htmlc, 
(dom_html_script_element *) node);
+                               break;
                        default:
                                break;
                        }
@@ -720,7 +773,39 @@ dom_default_action_DOMNodeInserted_cb(struct dom_event 
*evt, void *pw)
        }
 }
 
-/* callback for DOMNodeInserted end type */
+/* callback for DOMNodeInsertedIntoDocument end type */
+static void
+dom_default_action_DOMNodeInsertedIntoDocument_cb(struct dom_event *evt, void 
*pw)
+{
+       html_content *htmlc = pw;
+       dom_event_target *node;
+       dom_node_type type;
+       dom_exception exc;
+
+       exc = dom_event_get_target(evt, &node);
+       if ((exc == DOM_NO_ERR) && (node != NULL)) {
+               exc = dom_node_get_node_type(node, &type);
+               if ((exc == DOM_NO_ERR) && (type == DOM_ELEMENT_NODE)) {
+                       /* an element node has been modified */
+                       dom_html_element_type tag_type;
+
+                       exc = dom_html_element_get_tag_type(node, &tag_type);
+                       if (exc != DOM_NO_ERR) {
+                               tag_type = DOM_HTML_ELEMENT_TYPE__UNKNOWN;
+                       }
+
+                       switch (tag_type) {
+                       case DOM_HTML_ELEMENT_TYPE_SCRIPT:
+                               dom_SCRIPT_showed_up(htmlc, 
(dom_html_script_element *) node);
+                       default:
+                               break;
+                       }
+               }
+               dom_node_unref(node);
+       }
+}
+
+/* callback for DOMSubtreeModified end type */
 static void
 dom_default_action_DOMSubtreeModified_cb(struct dom_event *evt, void *pw)
 {
@@ -787,11 +872,13 @@ dom_event_fetcher(dom_string *type,
                  dom_default_action_phase phase,
                  void **pw)
 {
-       NSLOG(netsurf, DEEPDEBUG, "type:%s", dom_string_data(type));
+       NSLOG(netsurf, DEEPDEBUG, "phase:%d type:%s", phase, 
dom_string_data(type));
 
        if (phase == DOM_DEFAULT_ACTION_END) {
                if (dom_string_isequal(type, corestring_dom_DOMNodeInserted)) {
                        return dom_default_action_DOMNodeInserted_cb;
+               } else if (dom_string_isequal(type, 
corestring_dom_DOMNodeInsertedIntoDocument)) {
+                       return 
dom_default_action_DOMNodeInsertedIntoDocument_cb;
                } else if (dom_string_isequal(type, 
corestring_dom_DOMSubtreeModified)) {
                        return dom_default_action_DOMSubtreeModified_cb;
                }
@@ -847,6 +934,7 @@ html_create_html_data(html_content *c, const http_parameter 
*params)
 
        c->parser = NULL;
        c->parse_completed = false;
+       c->conversion_begun = false;
        c->document = NULL;
        c->quirks = DOM_DOCUMENT_QUIRKS_MODE_NONE;
        c->encoding = NULL;
@@ -948,6 +1036,7 @@ html_create_html_data(html_content *c, const 
http_parameter *params)
                                     (void *) &old_node_data);
        if (err != DOM_NO_ERR) {
                dom_hubbub_parser_destroy(c->parser);
+               c->parser = NULL;
                nsurl_unref(c->base_url);
                c->base_url = NULL;
 
@@ -1185,14 +1274,21 @@ bool html_can_begin_conversion(html_content *htmlc)
 {
        unsigned int i;
 
+       /* Cannot begin conversion if we already have */
+       if (htmlc->conversion_begun)
+               return false;
+
+       /* Cannot begin conversion if we're still fetching stuff */
        if (htmlc->base.active != 0)
                return false;
 
        for (i = 0; i != htmlc->stylesheet_count; i++) {
+               /* Cannot begin conversion if the stylesheets are modified */
                if (htmlc->stylesheets[i].modified)
                        return false;
        }
 
+       /* All is good, begin */
        return true;
 }
 
@@ -1206,6 +1302,10 @@ html_begin_conversion(html_content *htmlc)
        dom_string *node_name = NULL;
        dom_hubbub_error error;
 
+       if (htmlc->conversion_begun)
+               /* Conversion already began, so we are okay */
+               return true;
+
        /* The act of completing the parse can result in additional data
         * being flushed through the parser. This may result in new style or
         * script nodes, upon which the conversion depends. Thus, once we
@@ -1247,8 +1347,11 @@ html_begin_conversion(html_content *htmlc)
                return false;
        }
 
-       /* complete script execution */
-       html_script_exec(htmlc);
+       /* Conversion begins proper at this point */
+       htmlc->conversion_begun = true;
+
+       /* complete script execution, including deferred scripts */
+       html_script_exec(htmlc, true);
 
        /* fire a simple event that bubbles named DOMContentLoaded at
         * the Document.
diff --git a/content/handlers/html/html_internal.h 
b/content/handlers/html/html_internal.h
index 77354c3..a4ae1da 100644
--- a/content/handlers/html/html_internal.h
+++ b/content/handlers/html/html_internal.h
@@ -98,6 +98,7 @@ typedef struct html_content {
 
        dom_hubbub_parser *parser; /**< Parser object handle */
        bool parse_completed; /**< Whether the parse has been completed */
+       bool conversion_begun; /**< Whether or not the conversion has begun */
 
        /** Document tree */
        dom_document *document;
@@ -313,9 +314,10 @@ dom_hubbub_error html_process_script(void *ctx, dom_node 
*node);
  * 
http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#the-script-element
  *
  * \param htmlc html content.
+ * \param allow_defer allow deferred execution, if not, only async scripts.
  * \return NSERROR_OK error code.
  */
-nserror html_script_exec(html_content *htmlc);
+nserror html_script_exec(html_content *htmlc, bool allow_defer);
 
 /**
  * Free all script resources and references for a html content.
diff --git a/content/handlers/html/html_script.c 
b/content/handlers/html/html_script.c
index 80992b9..b404d2e 100644
--- a/content/handlers/html/html_script.c
+++ b/content/handlers/html/html_script.c
@@ -55,7 +55,7 @@ static script_handler_t *select_script_handler(content_type 
ctype)
 
 
 /* exported internal interface documented in html/html_internal.h */
-nserror html_script_exec(html_content *c)
+nserror html_script_exec(html_content *c, bool allow_defer)
 {
        unsigned int i;
        struct html_script *s;
@@ -71,7 +71,7 @@ nserror html_script_exec(html_content *c)
                }
 
                if ((s->type == HTML_SCRIPT_ASYNC) ||
-                   (s->type == HTML_SCRIPT_DEFER)) {
+                   (allow_defer && (s->type == HTML_SCRIPT_DEFER))) {
                        /* ensure script content is present */
                        if (s->data.handle == NULL)
                                continue;
@@ -200,6 +200,13 @@ convert_script_async_cb(hlcache_handle *script,
                html_begin_conversion(parent);
        }
 
+       /* if we have already started converting though, then we can handle the
+        * scripts as they come in.
+        */
+       else if (parent->conversion_begun) {
+               html_script_exec(parent, false);
+       }
+
        return NSERROR_OK;
 }
 
@@ -304,9 +311,11 @@ convert_script_sync_cb(hlcache_handle *script,
                }
 
                /* continue parse */
-               err = dom_hubbub_parser_pause(parent->parser, false);
-               if (err != DOM_HUBBUB_OK) {
-                       NSLOG(netsurf, INFO, "unpause returned 0x%x", err);
+               if (parent->parser != NULL) {
+                       err = dom_hubbub_parser_pause(parent->parser, false);
+                       if (err != DOM_HUBBUB_OK) {
+                               NSLOG(netsurf, INFO, "unpause returned 0x%x", 
err);
+                       }
                }
 
                break;
@@ -328,9 +337,11 @@ convert_script_sync_cb(hlcache_handle *script,
                s->already_started = true;
 
                /* continue parse */
-               err = dom_hubbub_parser_pause(parent->parser, false);
-               if (err != DOM_HUBBUB_OK) {
-                       NSLOG(netsurf, INFO, "unpause returned 0x%x", err);
+               if (parent->parser != NULL) {
+                       err = dom_hubbub_parser_pause(parent->parser, false);
+                       if (err != DOM_HUBBUB_OK) {
+                               NSLOG(netsurf, INFO, "unpause returned 0x%x", 
err);
+                       }
                }
 
                break;
@@ -402,6 +413,12 @@ exec_src_script(html_content *c,
                return DOM_HUBBUB_OK; /* dom error */
        }
 
+       if (c->parse_completed) {
+               /* After parse completed, all scripts are essentially async */
+               async = true;
+               defer = false;
+       }
+
        if (async) {
                /* asyncronous script */
                script_type = HTML_SCRIPT_ASYNC;
diff --git a/content/handlers/javascript/duktape/Node.bnd 
b/content/handlers/javascript/duktape/Node.bnd
index f14cfc1..fe24b3f 100644
--- a/content/handlers/javascript/duktape/Node.bnd
+++ b/content/handlers/javascript/duktape/Node.bnd
@@ -427,6 +427,7 @@ method Node::appendChild()
        dom_exception err;
        dom_node *spare;
 
+       NSLOG(dukky, DEEPDEBUG, "About to append %p to %p", other->node, 
priv->node);
        err = dom_node_append_child(priv->node, other->node, &spare);
        if (err != DOM_NO_ERR) return 0;
        dukky_push_node(ctx, spare);
diff --git a/test/js/inserted-script-async.js b/test/js/inserted-script-async.js
new file mode 100644
index 0000000..5552e27
--- /dev/null
+++ b/test/js/inserted-script-async.js
@@ -0,0 +1 @@
+console.log("External asynchronous dynamism!");
diff --git a/test/js/inserted-script-defer.js b/test/js/inserted-script-defer.js
new file mode 100644
index 0000000..2d89edd
--- /dev/null
+++ b/test/js/inserted-script-defer.js
@@ -0,0 +1 @@
+console.log("External deferred dynamism!");
diff --git a/test/js/inserted-script.html b/test/js/inserted-script.html
new file mode 100644
index 0000000..b1c381a
--- /dev/null
+++ b/test/js/inserted-script.html
@@ -0,0 +1,39 @@
+<html>
+  <head>
+    <title>Inserted script test</title>
+    <script>
+      /* After one second, insert an inline script element */
+      setTimeout(function() {
+      var div = document.createElement("DIV");
+      var script = document.createElement("SCRIPT");
+      var textnode = document.createTextNode("console.log(\"Dynamism\");");
+      script.appendChild(textnode);
+      div.appendChild(script);
+      document.body.appendChild(div);
+      }, 1000);
+      /* After two seconds, insert a script element for immediate fetch */
+      setTimeout(function() {
+      var script = document.createElement("SCRIPT");
+      script.setAttribute("src", "inserted-script.js");
+      document.body.appendChild(script);
+      }, 2000);
+      /* After three seconds, insert a script element for async fetch */
+      setTimeout(function() {
+      var script = document.createElement("SCRIPT");
+      script.setAttribute("src", "inserted-script-async.js");
+      script.setAttribute("async", "");
+      document.body.appendChild(script);
+      }, 3000);
+      /* After four seconds, insert a script element for deferred fetch */
+      setTimeout(function() {
+      var script = document.createElement("SCRIPT");
+      script.setAttribute("src", "inserted-script-defer.js");
+      script.setAttribute("defer", "");
+      document.body.appendChild(script);
+      }, 4000);
+    </script>
+  </head>
+  <body>
+    Check the log
+  </body>
+</html>
diff --git a/test/js/inserted-script.js b/test/js/inserted-script.js
new file mode 100644
index 0000000..f3a9548
--- /dev/null
+++ b/test/js/inserted-script.js
@@ -0,0 +1 @@
+console.log("External dynamism!");


-----------------------------------------------------------------------

Summary of changes:
 content/handlers/html/html.c                 |  111 +++++++++++++++++++++++++-
 content/handlers/html/html_internal.h        |    4 +-
 content/handlers/html/html_script.c          |   33 ++++++--
 content/handlers/javascript/duktape/Node.bnd |    1 +
 test/js/inserted-script-async.js             |    1 +
 test/js/inserted-script-defer.js             |    1 +
 test/js/inserted-script.html                 |   39 +++++++++
 test/js/inserted-script.js                   |    1 +
 8 files changed, 178 insertions(+), 13 deletions(-)
 create mode 100644 test/js/inserted-script-async.js
 create mode 100644 test/js/inserted-script-defer.js
 create mode 100644 test/js/inserted-script.html
 create mode 100644 test/js/inserted-script.js

diff --git a/content/handlers/html/html.c b/content/handlers/html/html.c
index 62f625f..30af90f 100644
--- a/content/handlers/html/html.c
+++ b/content/handlers/html/html.c
@@ -645,6 +645,56 @@ void html_finish_conversion(html_content *htmlc)
        dom_node_unref(html);
 }
 
+/* handler for a SCRIPT which has been added to a tree */
+static void
+dom_SCRIPT_showed_up(html_content *htmlc, dom_html_script_element *script)
+{
+       dom_exception exc;
+       dom_html_script_element_flags flags;
+       dom_hubbub_error res;
+       bool within;
+
+       if (!htmlc->enable_scripting) {
+               NSLOG(netsurf, INFO, "Encountered a script, but scripting is 
off, ignoring");
+               return;
+       }
+
+       NSLOG(netsurf, DEEPDEBUG, "Encountered a script, node %p showed up", 
script);
+
+       exc = dom_html_script_element_get_flags(script, &flags);
+       if (exc != DOM_NO_ERR) {
+               NSLOG(netsurf, DEEPDEBUG, "Unable to retrieve flags, giving 
up");
+               return;
+       }
+
+       if (flags & DOM_HTML_SCRIPT_ELEMENT_FLAG_PARSER_INSERTED) {
+               NSLOG(netsurf, DEBUG, "Script was parser inserted, skipping");
+               return;
+       }
+
+       exc = dom_node_contains(htmlc->document, script, &within);
+       if (exc != DOM_NO_ERR) {
+               NSLOG(netsurf, DEBUG, "Unable to determine if script was within 
document, ignoring");
+               return;
+       }
+
+       if (!within) {
+               NSLOG(netsurf, DEBUG, "Script was not within the document, 
ignoring for now");
+               return;
+       }
+
+       res = html_process_script(htmlc, (dom_node *) script);
+       if (res == DOM_HUBBUB_OK) {
+               NSLOG(netsurf, DEEPDEBUG, "Inserted script has finished 
running");
+       } else {
+               if (res == (DOM_HUBBUB_HUBBUB_ERR | HUBBUB_PAUSED)) {
+                       NSLOG(netsurf, DEEPDEBUG, "Inserted script has launced 
asynchronously");
+               } else {
+                       NSLOG(netsurf, DEEPDEBUG, "Failure starting script");
+               }
+       }
+}
+
 /* callback for DOMNodeInserted end type */
 static void
 dom_default_action_DOMNodeInserted_cb(struct dom_event *evt, void *pw)
@@ -693,6 +743,9 @@ dom_default_action_DOMNodeInserted_cb(struct dom_event 
*evt, void *pw)
                        case DOM_HTML_ELEMENT_TYPE_STYLE:
                                html_css_process_style(htmlc, (dom_node *) 
node);
                                break;
+                       case DOM_HTML_ELEMENT_TYPE_SCRIPT:
+                               dom_SCRIPT_showed_up(htmlc, 
(dom_html_script_element *) node);
+                               break;
                        default:
                                break;
                        }
@@ -720,7 +773,39 @@ dom_default_action_DOMNodeInserted_cb(struct dom_event 
*evt, void *pw)
        }
 }
 
-/* callback for DOMNodeInserted end type */
+/* callback for DOMNodeInsertedIntoDocument end type */
+static void
+dom_default_action_DOMNodeInsertedIntoDocument_cb(struct dom_event *evt, void 
*pw)
+{
+       html_content *htmlc = pw;
+       dom_event_target *node;
+       dom_node_type type;
+       dom_exception exc;
+
+       exc = dom_event_get_target(evt, &node);
+       if ((exc == DOM_NO_ERR) && (node != NULL)) {
+               exc = dom_node_get_node_type(node, &type);
+               if ((exc == DOM_NO_ERR) && (type == DOM_ELEMENT_NODE)) {
+                       /* an element node has been modified */
+                       dom_html_element_type tag_type;
+
+                       exc = dom_html_element_get_tag_type(node, &tag_type);
+                       if (exc != DOM_NO_ERR) {
+                               tag_type = DOM_HTML_ELEMENT_TYPE__UNKNOWN;
+                       }
+
+                       switch (tag_type) {
+                       case DOM_HTML_ELEMENT_TYPE_SCRIPT:
+                               dom_SCRIPT_showed_up(htmlc, 
(dom_html_script_element *) node);
+                       default:
+                               break;
+                       }
+               }
+               dom_node_unref(node);
+       }
+}
+
+/* callback for DOMSubtreeModified end type */
 static void
 dom_default_action_DOMSubtreeModified_cb(struct dom_event *evt, void *pw)
 {
@@ -787,11 +872,13 @@ dom_event_fetcher(dom_string *type,
                  dom_default_action_phase phase,
                  void **pw)
 {
-       NSLOG(netsurf, DEEPDEBUG, "type:%s", dom_string_data(type));
+       NSLOG(netsurf, DEEPDEBUG, "phase:%d type:%s", phase, 
dom_string_data(type));
 
        if (phase == DOM_DEFAULT_ACTION_END) {
                if (dom_string_isequal(type, corestring_dom_DOMNodeInserted)) {
                        return dom_default_action_DOMNodeInserted_cb;
+               } else if (dom_string_isequal(type, 
corestring_dom_DOMNodeInsertedIntoDocument)) {
+                       return 
dom_default_action_DOMNodeInsertedIntoDocument_cb;
                } else if (dom_string_isequal(type, 
corestring_dom_DOMSubtreeModified)) {
                        return dom_default_action_DOMSubtreeModified_cb;
                }
@@ -847,6 +934,7 @@ html_create_html_data(html_content *c, const http_parameter 
*params)
 
        c->parser = NULL;
        c->parse_completed = false;
+       c->conversion_begun = false;
        c->document = NULL;
        c->quirks = DOM_DOCUMENT_QUIRKS_MODE_NONE;
        c->encoding = NULL;
@@ -948,6 +1036,7 @@ html_create_html_data(html_content *c, const 
http_parameter *params)
                                     (void *) &old_node_data);
        if (err != DOM_NO_ERR) {
                dom_hubbub_parser_destroy(c->parser);
+               c->parser = NULL;
                nsurl_unref(c->base_url);
                c->base_url = NULL;
 
@@ -1185,14 +1274,21 @@ bool html_can_begin_conversion(html_content *htmlc)
 {
        unsigned int i;
 
+       /* Cannot begin conversion if we already have */
+       if (htmlc->conversion_begun)
+               return false;
+
+       /* Cannot begin conversion if we're still fetching stuff */
        if (htmlc->base.active != 0)
                return false;
 
        for (i = 0; i != htmlc->stylesheet_count; i++) {
+               /* Cannot begin conversion if the stylesheets are modified */
                if (htmlc->stylesheets[i].modified)
                        return false;
        }
 
+       /* All is good, begin */
        return true;
 }
 
@@ -1206,6 +1302,10 @@ html_begin_conversion(html_content *htmlc)
        dom_string *node_name = NULL;
        dom_hubbub_error error;
 
+       if (htmlc->conversion_begun)
+               /* Conversion already began, so we are okay */
+               return true;
+
        /* The act of completing the parse can result in additional data
         * being flushed through the parser. This may result in new style or
         * script nodes, upon which the conversion depends. Thus, once we
@@ -1247,8 +1347,11 @@ html_begin_conversion(html_content *htmlc)
                return false;
        }
 
-       /* complete script execution */
-       html_script_exec(htmlc);
+       /* Conversion begins proper at this point */
+       htmlc->conversion_begun = true;
+
+       /* complete script execution, including deferred scripts */
+       html_script_exec(htmlc, true);
 
        /* fire a simple event that bubbles named DOMContentLoaded at
         * the Document.
diff --git a/content/handlers/html/html_internal.h 
b/content/handlers/html/html_internal.h
index 77354c3..a4ae1da 100644
--- a/content/handlers/html/html_internal.h
+++ b/content/handlers/html/html_internal.h
@@ -98,6 +98,7 @@ typedef struct html_content {
 
        dom_hubbub_parser *parser; /**< Parser object handle */
        bool parse_completed; /**< Whether the parse has been completed */
+       bool conversion_begun; /**< Whether or not the conversion has begun */
 
        /** Document tree */
        dom_document *document;
@@ -313,9 +314,10 @@ dom_hubbub_error html_process_script(void *ctx, dom_node 
*node);
  * 
http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#the-script-element
  *
  * \param htmlc html content.
+ * \param allow_defer allow deferred execution, if not, only async scripts.
  * \return NSERROR_OK error code.
  */
-nserror html_script_exec(html_content *htmlc);
+nserror html_script_exec(html_content *htmlc, bool allow_defer);
 
 /**
  * Free all script resources and references for a html content.
diff --git a/content/handlers/html/html_script.c 
b/content/handlers/html/html_script.c
index 80992b9..b404d2e 100644
--- a/content/handlers/html/html_script.c
+++ b/content/handlers/html/html_script.c
@@ -55,7 +55,7 @@ static script_handler_t *select_script_handler(content_type 
ctype)
 
 
 /* exported internal interface documented in html/html_internal.h */
-nserror html_script_exec(html_content *c)
+nserror html_script_exec(html_content *c, bool allow_defer)
 {
        unsigned int i;
        struct html_script *s;
@@ -71,7 +71,7 @@ nserror html_script_exec(html_content *c)
                }
 
                if ((s->type == HTML_SCRIPT_ASYNC) ||
-                   (s->type == HTML_SCRIPT_DEFER)) {
+                   (allow_defer && (s->type == HTML_SCRIPT_DEFER))) {
                        /* ensure script content is present */
                        if (s->data.handle == NULL)
                                continue;
@@ -200,6 +200,13 @@ convert_script_async_cb(hlcache_handle *script,
                html_begin_conversion(parent);
        }
 
+       /* if we have already started converting though, then we can handle the
+        * scripts as they come in.
+        */
+       else if (parent->conversion_begun) {
+               html_script_exec(parent, false);
+       }
+
        return NSERROR_OK;
 }
 
@@ -304,9 +311,11 @@ convert_script_sync_cb(hlcache_handle *script,
                }
 
                /* continue parse */
-               err = dom_hubbub_parser_pause(parent->parser, false);
-               if (err != DOM_HUBBUB_OK) {
-                       NSLOG(netsurf, INFO, "unpause returned 0x%x", err);
+               if (parent->parser != NULL) {
+                       err = dom_hubbub_parser_pause(parent->parser, false);
+                       if (err != DOM_HUBBUB_OK) {
+                               NSLOG(netsurf, INFO, "unpause returned 0x%x", 
err);
+                       }
                }
 
                break;
@@ -328,9 +337,11 @@ convert_script_sync_cb(hlcache_handle *script,
                s->already_started = true;
 
                /* continue parse */
-               err = dom_hubbub_parser_pause(parent->parser, false);
-               if (err != DOM_HUBBUB_OK) {
-                       NSLOG(netsurf, INFO, "unpause returned 0x%x", err);
+               if (parent->parser != NULL) {
+                       err = dom_hubbub_parser_pause(parent->parser, false);
+                       if (err != DOM_HUBBUB_OK) {
+                               NSLOG(netsurf, INFO, "unpause returned 0x%x", 
err);
+                       }
                }
 
                break;
@@ -402,6 +413,12 @@ exec_src_script(html_content *c,
                return DOM_HUBBUB_OK; /* dom error */
        }
 
+       if (c->parse_completed) {
+               /* After parse completed, all scripts are essentially async */
+               async = true;
+               defer = false;
+       }
+
        if (async) {
                /* asyncronous script */
                script_type = HTML_SCRIPT_ASYNC;
diff --git a/content/handlers/javascript/duktape/Node.bnd 
b/content/handlers/javascript/duktape/Node.bnd
index f14cfc1..fe24b3f 100644
--- a/content/handlers/javascript/duktape/Node.bnd
+++ b/content/handlers/javascript/duktape/Node.bnd
@@ -427,6 +427,7 @@ method Node::appendChild()
        dom_exception err;
        dom_node *spare;
 
+       NSLOG(dukky, DEEPDEBUG, "About to append %p to %p", other->node, 
priv->node);
        err = dom_node_append_child(priv->node, other->node, &spare);
        if (err != DOM_NO_ERR) return 0;
        dukky_push_node(ctx, spare);
diff --git a/test/js/inserted-script-async.js b/test/js/inserted-script-async.js
new file mode 100644
index 0000000..5552e27
--- /dev/null
+++ b/test/js/inserted-script-async.js
@@ -0,0 +1 @@
+console.log("External asynchronous dynamism!");
diff --git a/test/js/inserted-script-defer.js b/test/js/inserted-script-defer.js
new file mode 100644
index 0000000..2d89edd
--- /dev/null
+++ b/test/js/inserted-script-defer.js
@@ -0,0 +1 @@
+console.log("External deferred dynamism!");
diff --git a/test/js/inserted-script.html b/test/js/inserted-script.html
new file mode 100644
index 0000000..b1c381a
--- /dev/null
+++ b/test/js/inserted-script.html
@@ -0,0 +1,39 @@
+<html>
+  <head>
+    <title>Inserted script test</title>
+    <script>
+      /* After one second, insert an inline script element */
+      setTimeout(function() {
+      var div = document.createElement("DIV");
+      var script = document.createElement("SCRIPT");
+      var textnode = document.createTextNode("console.log(\"Dynamism\");");
+      script.appendChild(textnode);
+      div.appendChild(script);
+      document.body.appendChild(div);
+      }, 1000);
+      /* After two seconds, insert a script element for immediate fetch */
+      setTimeout(function() {
+      var script = document.createElement("SCRIPT");
+      script.setAttribute("src", "inserted-script.js");
+      document.body.appendChild(script);
+      }, 2000);
+      /* After three seconds, insert a script element for async fetch */
+      setTimeout(function() {
+      var script = document.createElement("SCRIPT");
+      script.setAttribute("src", "inserted-script-async.js");
+      script.setAttribute("async", "");
+      document.body.appendChild(script);
+      }, 3000);
+      /* After four seconds, insert a script element for deferred fetch */
+      setTimeout(function() {
+      var script = document.createElement("SCRIPT");
+      script.setAttribute("src", "inserted-script-defer.js");
+      script.setAttribute("defer", "");
+      document.body.appendChild(script);
+      }, 4000);
+    </script>
+  </head>
+  <body>
+    Check the log
+  </body>
+</html>
diff --git a/test/js/inserted-script.js b/test/js/inserted-script.js
new file mode 100644
index 0000000..f3a9548
--- /dev/null
+++ b/test/js/inserted-script.js
@@ -0,0 +1 @@
+console.log("External dynamism!");


-- 
NetSurf Browser

_______________________________________________
netsurf-commits mailing list
[email protected]
http://listmaster.pepperfish.net/cgi-bin/mailman/listinfo/netsurf-commits-netsurf-browser.org

Reply via email to