Transparency on Demand
by Richard Vaughan


<!-- Listing 1  DTD etc omitted for brevity -->

<html>
   <head>
      <script type = "text/javascript" 
              src  = "MyLib.js"></script>
   </head>

   <body> ... </body>

</html>
  


// -- Listing 2 -----------------------

function DisplayMenu (...)
   {
   if (...) { LoadLib_XHR ("..."); }
   else     { LoadLib_XHR ("..."); }

   LoadStylesheet ("...");
   LoadLib_Scr    ("...");

   //
   // Code for displaying a menu   
   //
   
   } 

function LoadLib_XHR    (LibName) { ... }
function LoadLib_Scr    (LibName) { ... }
function LoadStylesheet (LibName) { ... }



// -- Listing 3 -----------------------

var MyObj =                // Define the object literally
   {
   MyMethod : function ()  // Define a method
      { 
      ...
      }

   };


function Proxy () { ... }  // Define our interloper


MyObj["MyMethod"] = Proxy; // Replace the reference 

...

MyObj.MyMethod ();         // Unbeknownst to the caller,  Proxy will now execute 



// -- Listing 4 -----------------------

function LoadLib_XHR (LibName) { ... }

function MyFunc () { MyOtherFunc (); }

function Proxy ()
   {
   LoadLib_XHR ("MyLib.js");      // Load synchronously
                                  // using XHR

   this["MyFunc"] = OriginalRef;  // Replace the ref here in case
                                  // MyFunc is recursive

   return OriginalRef.call (this, arguments);

   }

var OriginalRef = this["MyFunc"];

this["MyFunc"] = Proxy;           // Intercept is set at a distance from clients of MyFunc

  ...

MyFunc ();                        // Call routed through Proxy, library is loaded transparently
  ...

MyFunc ();                        // Call is now entirely conventional


// -- Contents of MyLib.js ------------

function MyOtherFunc () { ... }



// -- Listing 5 -----------------------

function LoadLib_XHR (LibName) { ... }

function SetIntercept (OwnerObject, MethodName, LibName)
   {
   var OriginalRef = OwnerObject[MethodName];

   OwnerObject[MethodName] = function () // Closure created here
      {
      LoadLib_XHR (LibName);

      OwnerObject[MethodName] = OriginalRef;

      return OriginalRef.call (this, arguments);

      }

   }

function MyFunc () { ... }

SetIntercept (this, "MyFunc", "MyLib.js");

...

MyFunc (); // Call routed through inner function

...

MyFunc (); // Call is now entirely conventional



<!-- Listing 6 -->

<html>
   <head>
      <script type = "text/javascript" src = "AspectJS.js"></script>
      <script type = "text/javascript">

      function LoadLib_XHR (LibName) { ... } // Use synchronous loader

      AJS.AddPrefix (this, "OnMouseClick", LoadLib_XHR, "Hello.js", 1); 

      function OnMouseClick ()
         {

         SayIt ();
  
         }
  
      </script>

   </head>

   <body onclick = "OnMouseClick ()"> ... </body>

</html>


// Contents of Hello.js

function SayIt () { alert ("Hello World"); }
 




