Load scripts asynchronously closure
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 28 May 2014 09:07:48 +0200
branchclosure
changeset 16085186733b7e07
parent 1607 ace1ff1087e7
child 1609 752f48257d4a
Load scripts asynchronously
rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java
     1.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java	Tue May 27 16:36:07 2014 +0200
     1.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java	Wed May 28 09:07:48 2014 +0200
     1.3 @@ -487,16 +487,34 @@
     1.4                  + "    name = replaceAll(name, '.', '_');\n"
     1.5                  + "    return name;\n"
     1.6                  + "  };\n"
     1.7 +                + "  var pending = [];\n"
     1.8 +                + "  var pendingClasses = [];\n"
     1.9 +                + "  function extensionLoaded(ev) {\n"
    1.10 +                + "    var at = pending.indexOf(ev.target);\n"
    1.11 +                + "    pending.splice(at, 1);\n"
    1.12 +                + "    if (pending.length === 0) {\n"
    1.13 +                + "      for (var i = 0; i < pendingClasses.length; i += 2) {\n"
    1.14 +                + "        var vm = pendingClasses[i];\n"
    1.15 +                + "        var n = pendingClasses[i + 1];\n"
    1.16 +                + "        vm.loadClass(n);\n"
    1.17 +                + "      }\n"
    1.18 +                + "      pendingClasses = [];\n"
    1.19 +                + "    }\n"
    1.20 +                + "  }\n"
    1.21 +                + "  function extensionError(ev) {\n"
    1.22 +                + "    console.log('error loading ' + ev.target.src);\n"
    1.23 +                + "    extensionLoaded(ev);\n"
    1.24 +                + "  }\n"
    1.25                  + "  function loadExtension(url) {\n"
    1.26                  + "      if (url.substring(url.length - 4) == '.jar')\n"
    1.27                  + "        url = url.substring(0, url.length - 4) + '.js';\n"
    1.28 -                + "      var xhr = new XMLHttpRequest();\n"
    1.29 -                + "      xhr.open('GET', url, false);\n"
    1.30 -                + "      xhr.send();\n"
    1.31                  + "      var script = document.createElement('script');\n"
    1.32                  + "      script.type = 'text/javascript';\n"
    1.33 -                + "      script.text = xhr.responseText;\n"
    1.34 +                + "      script.src = url;\n"
    1.35 +                + "      script.onload = extensionLoaded;\n"
    1.36 +                + "      script.onerror = extensionError;\n"
    1.37                  + "      document.getElementsByTagName('head')[0].appendChild(script);\n"
    1.38 +                + "      pending.push(script);\n"
    1.39                  + "  }\n"
    1.40                  + "  global.bck2brwsr = function() {\n"
    1.41                  + "    var args = Array.prototype.slice.apply(arguments);\n"
    1.42 @@ -570,7 +588,7 @@
    1.43                  + "        ['load__Ljava_lang_Object_2Ljava_lang_Object_2Ljava_lang_String_2_3Ljava_lang_Object_2_3B']\n"
    1.44                  + "        (vm, name, args, arr);\n"
    1.45                  + "    };\n"
    1.46 -                + "    loader.loadClass = function(name) {\n"
    1.47 +                + "    var loadClass = function(name) {\n"
    1.48                  + "      var attr = mangleClass(name);\n"
    1.49                  + "      var fn = vm[attr];\n"
    1.50                  + "      if (fn) return fn(false);\n"
    1.51 @@ -586,10 +604,22 @@
    1.52                  + "    if (vm['loadClass']) {\n"
    1.53                  + "      throw 'Cannot initialize the bck2brwsr VM twice!';\n"
    1.54                  + "    }\n"
    1.55 -                + "    vm['loadClass'] = loader.loadClass;\n"
    1.56 +                + "    vm['loadClass'] = loadClass;\n"
    1.57                  + "    vm['_reload'] = reload;\n"
    1.58                  + "    vm['loadBytes'] = loadBytes;\n"
    1.59                  + "    initVM();\n"
    1.60 +                + "    loader.loadClass = function(name) {\n"
    1.61 +                + "      if (pending.length === 0) {\n"
    1.62 +                + "        try {\n"
    1.63 +                + "          return loadClass(name);\n"
    1.64 +                + "        } catch (err) {\n"
    1.65 +                + "          if (pending.length === 0) throw err;\n"
    1.66 +                + "        }\n"
    1.67 +                + "      }\n"
    1.68 +                + "      pendingClasses.push(vm);\n"
    1.69 +                + "      pendingClasses.push(name);\n"
    1.70 +                + "      return null;\n"
    1.71 +                + "    }\n"
    1.72                  + "    return loader;\n"
    1.73                  + "  };\n");
    1.74              append(