Przeglądaj źródła

Refactor dynamic script loading. Add util.js:load_scripts()

Related to issue/pulls:
https://github.com/kanaka/noVNC/issues/194
https://github.com/kanaka/noVNC/pull/201
https://github.com/kanaka/noVNC/pull/202

In IE9, the window.onload event can fire before dynamically loaded
scripts have finished loading. This can result in either WebSocket (in
the case of vnc_auto.html) or RFB (in the case of vnc.html) not being
defined at the point when window.onload is called.

- Move the load_scripts routine from vnc.js to util.js (so that
  websockify can use it too). Also, refactor to work when load_scripts
  is called by a script that itself uses load_scripts. When the whole
  chain of dynamically loaded scripts is finished then call
  window.onscriptsload. Use this mechanism in all the places that
  depend on dynamic loading of scripts: vnc.html, vnc_auto.html,
  websock.js, tests/vnc_playback.html, and tests/vnc_perf.html.

- Use the new window.onscriptsload handler instead of window.onload.

- Remove include/start.js and do the script loading and startup event
  handling in include/ui.js instead.
Joel Martin 12 lat temu
rodzic
commit
6f4b1e4071
11 zmienionych plików z 73 dodań i 65 usunięć
  1. 0 2
      debian/novnc.install
  2. 3 2
      include/rfb.js
  3. 0 1
      include/start.js
  4. 5 0
      include/ui.js
  5. 39 0
      include/util.js
  6. 0 35
      include/vnc.js
  7. 3 12
      include/websock.js
  8. 6 2
      tests/vnc_perf.html
  9. 8 5
      tests/vnc_playback.html
  10. 3 4
      vnc.html
  11. 6 2
      vnc_auto.html

+ 0 - 2
debian/novnc.install

@@ -23,9 +23,7 @@ include/playback.js   /usr/share/novnc/include
 include/rfb.js   /usr/share/novnc/include
 include/ui.js   /usr/share/novnc/include
 include/util.js   /usr/share/novnc/include
-include/vnc.js   /usr/share/novnc/include
 include/websock.js   /usr/share/novnc/include
 include/webutil.js   /usr/share/novnc/include
 include/jsunzip.js   /usr/share/novnc/include
-include/start.js     /usr/share/novnc/include
 include/web-socket-js/*   /usr/share/novnc/include/web-socket-js

+ 3 - 2
include/rfb.js

@@ -1841,15 +1841,16 @@ that.clipboardPasteFrom = function(text) {
 };
 
 // Override internal functions for testing
-that.testMode = function(override_send) {
+that.testMode = function(override_send, data_mode) {
     test_mode = true;
-    that.recv_message = ws.testMode(override_send);
+    that.recv_message = ws.testMode(override_send, data_mode);
 
     checkEvents = function () { /* Stub Out */ };
     that.connect = function(host, port, password) {
             rfb_host = host;
             rfb_port = port;
             rfb_password = password;
+            init_vars();
             updateState('ProtocolVersion', "Starting VNC handshake");
         };
 };

+ 0 - 1
include/start.js

@@ -1 +0,0 @@
-window.onload = UI.load;

+ 5 - 0
include/ui.js

@@ -10,6 +10,11 @@
 /*jslint white: false, browser: true */
 /*global window, $D, Util, WebUtil, RFB, Display */
 
+// Load supporting scripts
+window.onscriptsload = function () { UI.load(); };
+Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js",
+                   "input.js", "display.js", "jsunzip.js", "rfb.js"]);
+
 var UI = {
 
 rfb_state : 'loaded',

+ 39 - 0
include/util.js

@@ -207,6 +207,45 @@ Util.conf_defaults = function(cfg, api, defaults, arr) {
  * Cross-browser routines
  */
 
+
+// Dynamically load scripts without using document.write()
+// Reference: http://unixpapa.com/js/dyna.html
+//
+// Handles the case where load_scripts is invoked from a script that
+// itself is loaded via load_scripts. Once all scripts are loaded the
+// window.onscriptsloaded handler is called (if set).
+Util.get_include_uri = function() {
+    return (typeof INCLUDE_URI !== "undefined") ? INCLUDE_URI : "include/";
+}
+Util._pending_scripts = [];
+Util.load_scripts = function(files) {
+    var head = document.getElementsByTagName('head')[0],
+        ps = Util._pending_scripts;
+    for (var f=0; f<files.length; f++) {
+        var script = document.createElement('script');
+        script.type = 'text/javascript';
+        script.src = Util.get_include_uri() + files[f];
+        //console.log("loading script: " + Util.get_include_uri() +  files[f]);
+        head.appendChild(script);
+        ps.push(script);
+        script.onload = script.onreadystatechange = function (e) {
+            if (!this.readyState || 
+                this.readyState == 'complete' ||
+                this.readyState == 'loaded') {
+                this.onload = this.onreadystatechange = null;
+                if (ps.indexOf(this) >= 0) {
+                    //console.log("loaded script: " + this.src);
+                    ps.splice(ps.indexOf(this), 1);
+                }
+                // Call window.onscriptsload after last script loads
+                if (ps.length === 0 && window.onscriptsload) {
+                    window.onscriptsload();
+                }
+            }
+        }
+    }
+}
+
 // Get DOM element position on page
 Util.getPosition = function (obj) {
     var x = 0, y = 0;

+ 0 - 35
include/vnc.js

@@ -1,35 +0,0 @@
-/*
- * noVNC: HTML5 VNC client
- * Copyright (C) 2012 Joel Martin
- * Licensed under MPL 2.0 (see LICENSE.txt)
- *
- * See README.md for usage and integration instructions.
- */
-
-/*jslint evil: true */
-/*global window, document, INCLUDE_URI */
-
-/*
- * Load supporting scripts
- */
-function get_INCLUDE_URI() {
-    return (typeof INCLUDE_URI !== "undefined") ? INCLUDE_URI : "include/";
-}
-/*
- * Dynamically load a script without using document.write()
- * Reference: http://unixpapa.com/js/dyna.html
- */
-function load_scripts(base, files) {
-    var head = document.getElementsByTagName('head')[0];
-    for (var i=0; i<files.length; i++) {
-        var script = document.createElement('script');
-        script.type = 'text/javascript';
-        script.src = base + files[i];
-        head.appendChild(script);
-    }
-}
-
-load_scripts(get_INCLUDE_URI(),
-    ["util.js", "webutil.js", "base64.js", "websock.js", "des.js",
-     "input.js", "display.js", "rfb.js", "jsunzip.js"]);
-

+ 3 - 12
include/websock.js

@@ -35,23 +35,14 @@ if (window.WebSocket && !window.WEB_SOCKET_FORCE_FLASH) {
 
     Websock_native = false;
     (function () {
-        function get_INCLUDE_URI() {
-            return (typeof INCLUDE_URI !== "undefined") ?
-                INCLUDE_URI : "include/";
-        }
-
-        var start = "<script src='" + get_INCLUDE_URI(),
-            end = "'><\/script>", extra = "";
-
-        window.WEB_SOCKET_SWF_LOCATION = get_INCLUDE_URI() +
+        window.WEB_SOCKET_SWF_LOCATION = Util.get_include_uri() +
                     "web-socket-js/WebSocketMain.swf";
         if (Util.Engine.trident) {
             Util.Debug("Forcing uncached load of WebSocketMain.swf");
             window.WEB_SOCKET_SWF_LOCATION += "?" + Math.random();
         }
-        extra += start + "web-socket-js/swfobject.js" + end;
-        extra += start + "web-socket-js/web_socket.js" + end;
-        document.write(extra);
+        Util.load_scripts(["web-socket-js/swfobject.js",
+                           "web-socket-js/web_socket.js"]);
     }());
 }
 

+ 6 - 2
tests/vnc_perf.html

@@ -39,11 +39,15 @@
     <script type="text/javascript">
         var INCLUDE_URI= "../include/";
     </script>
-    <script src="../include/vnc.js"></script>
+    <script src="../include/util.js"></script>
     <script src="../include/playback.js"></script>
     <script src="../data/multi.js"></script>
 
     <script>
+        // Load supporting scripts
+        Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js",
+                           "input.js", "display.js", "jsunzip.js", "rfb.js"]);
+
         var start_time, VNC_frame_data, pass, passes, encIdx,
             encOrder = ['raw', 'rre', 'hextile', 'tightpng', 'copyrect'],
             encTot = {}, encMin = {}, encMax = {},
@@ -188,7 +192,7 @@
                 " (min/avg/max)");
         }
 
-        window.onload = function() {
+        window.onscriptsload = function() {
             var i, enc;
             dbgmsg("Frame lengths:");
             for (i = 0; i < encOrder.length; i++) {

+ 8 - 5
tests/vnc_playback.html

@@ -41,8 +41,8 @@
     <script type="text/javascript">
         var INCLUDE_URI= "../include/";
     </script>
-    <script src="../include/vnc.js"></script>
-    <script src="../include/playback.js"></script>
+    <script src="../include/util.js"></script>
+    <script src="../include/webutil.js"></script>
 
     <script>
         var fname, start_time;
@@ -55,10 +55,13 @@
         }
 
         fname = WebUtil.getQueryVar('data', null);
-
         if (fname) {
             message("Loading " + fname);
-            document.write('<script src="' + fname + '"><\/script>');
+            // Load supporting scripts
+            Util.load_scripts(["base64.js", "websock.js", "des.js",
+                            "input.js", "display.js", "jsunzip.js", "rfb.js",
+                            "playback.js", fname]);
+
         } else {
             message("Must specify data=FOO in query string.");
         }
@@ -115,7 +118,7 @@
 
         }
 
-        window.onload = function() {
+        window.onscriptsload = function () {
             iterations = WebUtil.getQueryVar('iterations', 3);
             $D('iterations').value = iterations;
             mode = WebUtil.getQueryVar('mode', 3);

+ 3 - 4
vnc.html

@@ -39,10 +39,6 @@
         src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
     -->
 
-    <script src="include/vnc.js"></script>
-    <script src="include/ui.js"></script>
-    <script src="include/start.js"></script>
-
 </head>
 
 <body>
@@ -178,5 +174,8 @@
         </div>
 
     </div>
+    <script src="include/util.js"></script>
+    <script src="include/ui.js"></script>
+
  </body>
 </html>

+ 6 - 2
vnc_auto.html

@@ -17,7 +17,7 @@
         <script type='text/javascript' 
             src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
         -->
-        <script src="include/vnc.js"></script>
+        <script src="include/util.js"></script>
     </head>
 
     <body style="margin: 0px;">
@@ -41,6 +41,10 @@
         /*global window, $, Util, RFB, */
         "use strict";
 
+        // Load supporting scripts
+        Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js",
+                           "input.js", "display.js", "jsunzip.js", "rfb.js"]);
+
         var rfb;
 
         function passwordRequired(rfb) {
@@ -84,7 +88,7 @@
             }
         }
 
-        window.onload = function () {
+        window.onscriptsload = function () {
             var host, port, password, path, token;
 
             $D('sendCtrlAltDelButton').style.display = "inline";