Subversion Repositories wimsdev

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2.  
  3.         DynAPI Distribution
  4.  
  5.         Dynamic Loading extension to dynapi.library
  6.  
  7.  
  8.  
  9.         The DynAPI Distribution is distributed under the terms of the GNU LGPL license.
  10.  
  11. */
  12.  
  13.  
  14.  
  15. // begin loading the object
  16.  
  17. DynAPILibrary.prototype.load = function(n,fn) {
  18.  
  19.         var list = this._queue(n,null,arguments[2]);
  20.  
  21.         //return dynapi.debug.print('going to load: '+list);
  22.  
  23.         if (list.length) {
  24.  
  25.                 var s,src;
  26.  
  27.                 for (var i=0;i<list.length;i++) {
  28.  
  29.                         src = list[i];
  30.  
  31.                         s = this.scripts[list[i]];
  32.  
  33.                         if (i==list.length-1 && fn!=null) s.fn = fn;
  34.  
  35.                         this.loadList[this.loadList.length] = src;
  36.  
  37.                 }
  38.  
  39.                 this._load();
  40.  
  41.         }
  42.  
  43.         else if (fn) fn();
  44.  
  45. };
  46.  
  47.  
  48.  
  49. // reload the object
  50.  
  51. DynAPILibrary.prototype.reload = function(n,fn,force) {
  52.  
  53.         var s = this.objects[n];
  54.  
  55.         if (s) {
  56.  
  57.                 s.loaded = false;
  58.  
  59.                 this.load(n,fn,force);
  60.  
  61.         }
  62.  
  63. };
  64.  
  65.  
  66.  
  67. // load a script that is not added to the library
  68.  
  69. DynAPILibrary.prototype.loadScript = function(src,fn) {
  70.  
  71.         if (!this.scripts[src]) {
  72.  
  73.                 var n = 'unnamed'+this._c++;
  74.  
  75.                 s = this.add(n,src);  // generate a name for the script
  76.  
  77.                 s.unnamed = true;
  78.  
  79.                 s.fn = null;
  80.  
  81.                 s.dep = [];
  82.  
  83.                 this.load(n,fn);
  84.  
  85.         }
  86.  
  87. };
  88.  
  89.  
  90.  
  91. // reload a script
  92.  
  93. DynAPILibrary.prototype.reloadScript = function(src,fn,force) {
  94.  
  95.         var s=this.scripts[src];
  96.  
  97.         if(s) this.load(s.objects[0],fn,force);
  98.  
  99. }
  100.  
  101.  
  102.  
  103. // inserts the script element into the page
  104.  
  105. DynAPILibrary.prototype._load = function() {
  106.  
  107.         if (this.busy) return; // dynapi.debug.print('Library Warning: busy');
  108.  
  109.         else {
  110.  
  111.                 if (this.loadIndex<this.loadList.length-1) {
  112.  
  113.                         this.busy = true;
  114.  
  115.                         this.loadIndex++;
  116.  
  117.                         var src = this.loadList[this.loadIndex];
  118.  
  119.                         //if (!confirm('load: '+src+' ?')) return;
  120.  
  121.                         var rsrc = src + '?'+Math.random();     // random ensures cached files are not loaded
  122.  
  123.                         var s = this.scripts[src];
  124.  
  125.                         if (dynapi.ua.ns4) {
  126.  
  127.                                 // delete the constructors
  128.  
  129.                                 for (var j=0;j<s.objects.length;j++) {
  130.  
  131.                                         var n = s.objects[j];
  132.  
  133.                                         if (dynapi.frame[n]) {
  134.  
  135.                                                 dynapi.frame[n] = null;
  136.  
  137.                                                 if (s.pkg) dynapi.frame[s.pkg+'.'+n] = null;
  138.  
  139.                                         }
  140.  
  141.                                 }
  142.  
  143.                                 //NS4 does not like "/" inside the ?name=value
  144.  
  145.                                 src=src.replace(/\//g,'+'); //substitute "/" for "+"
  146.  
  147.                                 this.elm.src = dynapi._path+'ext/library.html?js='+src;
  148.  
  149.                         }
  150.  
  151.                         else if (dynapi.ua.ie && (dynapi.ua.v==4 || dynapi.ua.mac)) {
  152.  
  153.                                 dynapi.frame.document.body.insertAdjacentHTML('beforeEnd','<script type="text/javascript" language="javascript" src="'+rsrc+'" defer><\/script>');
  154.  
  155.                                 this._export(src);
  156.  
  157.                         }
  158.  
  159.                         else {
  160.  
  161.                                 var elm = s.elm = dynapi.frame.document.createElement('script');
  162.  
  163.                                 elm.src = rsrc;
  164.  
  165.                                 elm.type = 'text/javascript';
  166.  
  167.                                 elm.defer = true;
  168.  
  169.                                 if (dynapi.ua.ie) {
  170.  
  171.                                         elm.C = 0;
  172.  
  173.                                         var o = this;
  174.  
  175.                                         elm.onreadystatechange = function() {
  176.  
  177.                                                 elm.C++;
  178.  
  179.                                                 if (elm.C==2 || elm.readyState=="complete") {  // use 2nd statechange for onload
  180.  
  181.                                                         o._export(src);
  182.  
  183.                                                 }
  184.  
  185.                                         }
  186.  
  187.                                 }
  188.  
  189.                                 dynapi.frame.document.getElementsByTagName('head')[0].appendChild(elm);
  190.  
  191.                                
  192.  
  193.                                 // I could not find way to know when the script is complete in Moz v0.9.3
  194.  
  195.                                 if (dynapi.ua.ns6) setTimeout(this+'._export("'+src+'")',100);
  196.  
  197.                         }
  198.  
  199.                 }
  200.  
  201.         }
  202.  
  203. };
  204.  
  205.  
  206.  
  207. // executed after a script is finished loading, run main() functions
  208.  
  209. DynAPILibrary.prototype._export = function(src) {
  210.  
  211.         var src = this.loadList[this.loadIndex];
  212.  
  213.         var s = this.scripts[src];
  214.  
  215.         if (s) {
  216.  
  217.                 this._register(s);
  218.  
  219.  
  220.  
  221.                 // run elm.main)() before global main()
  222.  
  223.                 if (dynapi.ua.ns4 && typeof(this.elm.main)=="function") {
  224.  
  225.                         this.elm.main();
  226.  
  227.                         this.elm.main = null;
  228.  
  229.                 }
  230.  
  231.                                
  232.  
  233.                 // run global main() if available
  234.  
  235.                 if (typeof(main)=="function") {
  236.  
  237.                         main();
  238.  
  239.                         main = null;
  240.  
  241.                 }
  242.  
  243.  
  244.  
  245.                 // clear out all functions in the layer's scope
  246.  
  247.                 if (dynapi.ua.ns4) {
  248.  
  249.                         for (var i in this.elm) {
  250.  
  251.                                 if (typeof(this.elm[i])=="function") delete this.elm[i];
  252.  
  253.                         }
  254.  
  255.                 }
  256.  
  257.                 this.busy = false;
  258.  
  259.  
  260.  
  261.                 // load next file
  262.  
  263.                 this._load();
  264.  
  265.         }
  266.  
  267.         //else return alert('Library Error: unknown script '+src);
  268.  
  269. };
  270.  
  271.  
  272.  
  273. // registers the script as loaded, exports the objects
  274.  
  275. DynAPILibrary.prototype._register = function(s) {
  276.  
  277.         //dynapi.debug.print('loaded "'+s.src+'"');
  278.  
  279.         s.loaded = true;
  280.  
  281.         s.queued = false;
  282.  
  283.         if (!s.unnamed) {
  284.  
  285.                 var n,found;
  286.  
  287.                 // loop through each object that the script contains
  288.  
  289.                 for (var i=0;i<s.objects.length;i++) {
  290.  
  291.                         found = false;
  292.  
  293.                         n = s.objects[i];
  294.  
  295.                                        
  296.  
  297.                         // scope local objects in the layer to the DynAPI frame
  298.  
  299.                         if (dynapi.ua.ns4 && this.elm && typeof(this.elm[n])!="undefined") {
  300.  
  301.                                 dynapi.frame[n] = this.elm[n];
  302.  
  303.                                 found = true;
  304.  
  305.                         }
  306.  
  307.                         else if (typeof(dynapi.frame[n])!="undefined") found = true;
  308.  
  309.                         else if (n.indexOf('.')>0) {
  310.  
  311.                                 var ns = n.split('.'), o = dynapi.frame, b = false;
  312.  
  313.                                 for (var j=0;j<ns.length;j++) {
  314.  
  315.                                         o = o[ns[j]];
  316.  
  317.                                 }
  318.  
  319.                                 if (typeof(o)!="undefined") found = true;
  320.  
  321.                         }
  322.  
  323.                         else if (typeof(dynapi[n])!="undefined") found = true;
  324.  
  325.                        
  326.  
  327.                         if (found) {
  328.  
  329.                                 if (s.pkg) {
  330.  
  331.                                         // make package link: dynapi.api.DynLayer = DynLayer
  332.  
  333.                                         if (s.pkg!="dynapi") this.packages[s.pkg][n] = dynapi.frame[n];
  334.  
  335.                                         n = s.pkg+'.'+n;
  336.  
  337.                                 }
  338.  
  339.                                 dynapi.debug.print('loaded ['+n+']');
  340.  
  341.                         }
  342.  
  343.                         else {
  344.  
  345.                                 dynapi.debug.print('Library Error: could not find ['+n+']');
  346.  
  347.                         }
  348.  
  349.                 }
  350.  
  351.         }
  352.  
  353.         // run handler if available
  354.  
  355.         if (s.fn) {
  356.  
  357.                 s.fn();
  358.  
  359.                 delete s.fn;
  360.  
  361.         }
  362.  
  363. };
  364.  
  365.  
  366.  
  367. // called from /lib/dynapi/library.html to write the <script>, NS4 only
  368.  
  369. DynAPILibrary.prototype._handleLoad = function(elm) {
  370.  
  371.         var args = dynapi.functions.getURLArguments(elm.src);
  372.  
  373.         var js = args["js"];
  374.  
  375.         if (js) {
  376.  
  377.                 js=js.replace(/\+/g,'/'); // convert + to /
  378.  
  379.                 if (js.indexOf('http')!=0) {
  380.  
  381.                         var l = dynapi.frame.document.location;
  382.  
  383.                         if (js.substr(0,1)=='/') js = l.port+'//'+host+src;
  384.  
  385.                         else js = dynapi.documentPath+js;
  386.  
  387.                 }
  388.  
  389.                 elm.document.write('<script type="text/javascript" language="JavaScript" src="'+js+'?r'+Math.random()+'"><\/script>');
  390.  
  391.                 elm.document.close();
  392.  
  393.                 elm.onload = function() {
  394.  
  395.                         dynapi.library._export(js);
  396.  
  397.                 }
  398.  
  399.         }
  400.  
  401. };
  402.  
  403.  
  404.  
  405. // inserts the layer for NS4, register included scripts
  406.  
  407. DynAPILibrary.prototype._create = function() {
  408.  
  409.         // ensure a previous main function is wiped out
  410.  
  411.         if (typeof(main)=="function") main = null;
  412.  
  413.                
  414.  
  415.         // register objects from scripts included by dynapi.library.include() or manually
  416.  
  417.         var s,n;
  418.  
  419.         for (var i in this.scripts) {
  420.  
  421.                 s = this.scripts[i];
  422.  
  423.                 n=s.objects[0];
  424.  
  425.                 if(s.pkg=='dynapi.functions') { // used to avoid conflicts with intrinsic objects such as String, Image, Date and Math objects
  426.  
  427.                         if(dynapi.functions[n]) this._register(s);
  428.  
  429.                 }
  430.  
  431.                 else if (s.loaded || (s.objects[0] && dynapi.frame[s.objects[0]])) this._register(s);
  432.  
  433.         }
  434.  
  435.        
  436.  
  437.         // create NS4 layer to load scripts into
  438.  
  439.         if (dynapi.ua.ns4) this.elm = new Layer(0, dynapi.frame);
  440.  
  441.         this.busy = false;
  442.  
  443.        
  444.  
  445.         // load any scripts before proceeding
  446.  
  447.         if (this.loadList.length) {
  448.  
  449.                 var s = this.scripts[this.loadList[this.loadList.length-1]];
  450.  
  451.                 s.fn = function() {
  452.  
  453.                         setTimeout('dynapi._onLoad()',1);
  454.  
  455.                 }
  456.  
  457.                 this._load();
  458.  
  459.         }
  460.  
  461.         else setTimeout('dynapi._onLoad()',1);
  462.  
  463. };
  464.  
  465.