Subversion Repositories wimsdev

Rev

Rev 20 | Blame | Compare with Previous | Last modification | View Log | RSS feed

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