Subversion Repositories wimsdev

Rev

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

  1. /*
  2.         DynAPI Distribution
  3.         DynEvent, EventObject, DynElement Classes
  4.  
  5.         The DynAPI Distribution is distributed under the terms of the GNU LGPL license.
  6. */
  7.  
  8. function DynEvent(type,src) {
  9.         this.type = type;
  10.         this.src = src;
  11.         this.origin = src;
  12.         this.propagate = true;
  13.         this.bubble = false;
  14.         this.bubbleChild = null;
  15.         this.defaultValue = true;
  16. };
  17. var protoEvent = DynEvent.prototype;
  18. protoEvent.getType = function() {return this.type};
  19. protoEvent.getSource = function() {return this.src};
  20. protoEvent.getOrigin=function() {return this.origin};
  21. protoEvent.stopPropagation = function() {this.propagate = false};
  22. protoEvent.preventBubble = function() {this.bubble = false};
  23. protoEvent.preventDefault = function() {this.defaultValue = false};
  24. protoEvent.getBubbleChild = function() {return this.bubbleChild};
  25.  
  26. function EventObject() {
  27.         this.DynObject = DynObject;
  28.         this.DynObject();
  29.         this._listeners = [];
  30. };
  31. EventObject._SubClass={};
  32.  
  33. protoEvent = dynapi.setPrototype('EventObject','DynObject');
  34. protoEvent.addEventListener = function(el) {
  35.         if (el) {
  36.                 for (var i=0;i<this._listeners.length;i++) if (this._listeners[i]==el) return;
  37.                 this._listeners[this._listeners.length] = el;
  38.                 // Use onCreate() and onPrecreate() function for create events
  39.                 this._hasContentEvents=(el['oncontentchange'])? true:this._hasContentEvents;
  40.                 this._hasLocationEvents=(el['onlocationchange'])? true:this._hasLocationEvents;
  41.                 this._hasResizeEvents=(el['onresize'])? true:this._hasResizeEvents;
  42.                 this._hasDragEvents=(el['ondragstart']||el['ondragmove']||
  43.                                                         el['ondragend']||el['ondragdrop']||
  44.                                                         el['ondragover']||el['ondragout'])? true:this._hasDragEvents;
  45.  
  46.                 if (this.captureMouseEvents) {
  47.                         this._hasMouseEvents = this._hasMouseEvents||(el.onmousedown || el.onmouseup || el.onmouseover || el.onmouseout || el.onclick || el.ondblclick);
  48.                         if (this._created && !this._hasMouseEvents) this.captureMouseEvents();
  49.                 }
  50.                 if (this.captureKeyEvents)
  51.                         if (this._created && !this._hasKeyEvents && (el.onkeydown || el.onkeyup || el.onkeypress)) this.captureKeyEvents();
  52.         }
  53. };
  54. protoEvent.removeEventListener = function(el) {
  55.         if (el) {
  56.                 DynAPI.functions.removeFromArray(this._listeners, el, false);
  57.                 if (!this._listeners.length && this.releaseMouseEvents && this.getClassName()!='DynDocument') this.releaseMouseEvents();
  58.                 if (!this._listeners.length && this.releaseKeyEvents && this.getClassName()!='DynDocument') this.releaseKeyEvents();
  59.         }
  60. };
  61. protoEvent.removeAllEventListeners = function() {
  62.         this._listeners = [];
  63. };
  64. protoEvent.invokeEvent = function(type,e,args) {
  65.         if (!e) e = new DynEvent(type,this);
  66.         e.src = this;
  67.         e.type = type;
  68.  
  69.         // Check for subclassing
  70.         var clsFn=EventObject._SubClass[this+'_'+type];
  71.         if(clsFn) {
  72.                 if (clsFn(e,args)==false) return;
  73.         };
  74.  
  75.         if (this._listeners.length) for (var i=0;i<this._listeners.length;i++) {
  76.                 if (this._listeners[i]["on"+type]) this._listeners[i]["on"+type](e,args);
  77.                 if (!e.propagate) break;
  78.         }
  79.         if (this["on"+type]) this["on"+type](e,args);
  80.         if (e.bubble && this.parent) {
  81.                 //if ((type=="mouseover" || type=="mouseout") && e._relative==this.parent) return;
  82.                 e.x += this.x;
  83.                 e.y += this.y;
  84.                 e.bubbleChild = this;
  85.                 this.parent.invokeEvent(type,e,args);
  86.         }
  87. };
  88.  
  89. // Add subClassEvent() function to dynapi.functions
  90. dynapi.functions.subClassEvent = function(type,eobj,fn){
  91.         var ek=eobj+'_'+type;
  92.         var cls=EventObject._SubClass;
  93.         if(typeof(fn)=='function') cls[ek]=fn;
  94.         else if(!fn && cls[ek]) delete cls[ek];
  95. };
  96.  
  97. function DynElement() {
  98.         this.EventObject = EventObject;
  99.         this.EventObject();
  100.         this.isChild = false;
  101.         this._created = false;
  102.         this.parent = null;
  103.         this._dyndoc = null;
  104.         this.children = [];
  105.         this._childAnchors = [];
  106. };
  107. DynElement._flagCreate = function(c){ // much faster than using DynElemnt._flagEvent
  108.         var ch=c.children;
  109.         c._created = true;
  110.         if (c._hasCreateFn) c._flagCreateEvent('create');
  111.         for (var i=0; i<ch.length; i++) this._flagCreate(ch[i]);
  112. };
  113. DynElement._flagPreCreate = function(c){
  114.         var ch=c.children;
  115.         if (c._hasPCreateFn) c._flagCreateEvent('precreate');
  116.         for (var i=0; i<ch.length; i++) this._flagPreCreate(ch[i]);
  117. };
  118. DynElement._flagEvent = function(c,type) {
  119.         var ch=c.children;
  120.         c.invokeEvent(type);
  121.         for (var i=0; i<ch.length; i++) this._flagEvent(ch[i],type);
  122. };
  123.  
  124. protoEvent = dynapi.setPrototype('DynElement','EventObject');
  125. protoEvent.addChild = function(c,alias,inlineID) {
  126.         if (!c) return dynapi.debug.print("Error: no object sent to [DynLayer].addChild()");
  127.         if (c.isChild) c.removeFromParent();
  128.         c.isChild = true;
  129.         c.parent = this;
  130.         if (c._saveAnchor) {
  131.                 c.setAnchor(c._saveAnchor);
  132.                 c._saveAnchor = null;
  133.                 delete c._saveAnchor;
  134.         }
  135.         if(alias) this[alias]=c;
  136.         if(inlineID) c.setID(inlineID,true);
  137.         if (this._created)      {
  138.                 if (c.isInline) c._createInline();
  139.                 else c._create();
  140.         }
  141.         this.children[this.children.length] = c;
  142.         return c;
  143. };
  144. protoEvent.removeChild = function(c) {
  145.         var l = this.children.length;
  146.         for (var i=0;i<l && this.children[i]!=c;i++);
  147.         if (i!=l) {
  148.                 c._remove();
  149.                 c._created = false;
  150.                 c.isChild = false;
  151.                 c.parent = null;
  152.                 c.dyndoc = null;
  153.                 this.children[i] = this.children[l-1];
  154.                 this.children[l-1] = null;
  155.                 this.children.length--;
  156.         }
  157. };
  158. protoEvent.deleteChild = function(c) {
  159.         c.removeFromParent();
  160.         c._delete();
  161. };
  162. protoEvent.deleteAllChildren = function() {
  163.         var l = this.children.length;
  164.         for(var i=0;i<l;i++) {
  165.                 this.children[i].deleteFromParent();
  166.                 delete this.children[i];
  167.         }
  168.         this.children = [];
  169. };
  170. protoEvent.deleteFromParent = function () {
  171.         if (this.parent) this.parent.deleteChild(this);
  172. };
  173. protoEvent.removeFromParent = function () {
  174.         if (this.parent) this.parent.removeChild(this);
  175. };
  176. protoEvent._create = protoEvent._createInLine = protoEvent._createInserted = protoEvent._remove = protoEvent._delete = protoEvent._destroy = dynapi.functions.Null;
  177.  
  178. protoEvent.getChildren = function() {return this.children};
  179. protoEvent.getAllChildren = function() {
  180.         var ret = [];
  181.         var temp;
  182.         var l = this.children.length;
  183.         for(var i=0;i<l;i++) {
  184.                 ret[this.children[i].id] = this.children[i];
  185.                 temp = this.children[i].getAll();
  186.                 for(var j in temp) ret[j] = temp[j];
  187.         }
  188.         return ret;
  189. };
  190. protoEvent.getParents = function(l) {
  191.         if (l==null) l = [];
  192.         if (this.parent) {
  193.                 l[l.length] = this.parent;
  194.                 l = this.parent.getParents(l);
  195.         }
  196.         return l;
  197. };
  198. protoEvent.isParentOf = function(c) {
  199.         if (c) {
  200.                 var p = c.getParents();
  201.                 for (var i=0;i<p.length;i++) {
  202.                         if (p[i]==this) return true;
  203.                 }
  204.         }
  205.         return false;
  206. };
  207. protoEvent.isChildOf = function(p) {
  208.         if (!p) return false;
  209.         return p.isParentOf(this);
  210. };
  211. // New onPreCreate() and onCreate() callback functions
  212. protoEvent.onCreate = function(fn){
  213.         if(!fn) return;
  214.         if(!this._cfn){this._fn=0;this._cfn=[];}
  215.         var s='create'+this._fn++;
  216.         this._cfn[s]='create';
  217.         this._hasCreateFn=true;
  218.         this[s]=fn;
  219. };
  220. protoEvent.onPreCreate = function(fn){
  221.         if(!fn) return;
  222.         if(!this._cfn){this._fn=0;this._cfn=[];}
  223.         var s='precreate'+this._fn++;
  224.         this._cfn[s]='precreate';
  225.         this._hasPCreateFn=true;
  226.         this[s]=fn;
  227. };
  228. protoEvent._flagCreateEvent = function(t){
  229.         for(var i in this._cfn){
  230.                 if(this._cfn[i]==t) this[i]();
  231.         };
  232. };
  233.  
  234. protoEvent.updateAnchor = function() {
  235.         this.parent._updateAnchor(this.id);
  236. };
  237. protoEvent._updateAnchor = function(id) {
  238.         if (!id) return;
  239.         var dlyr = DynObject.all[id];
  240.         var a = this._childAnchors[id];
  241.         var tw = this.w;
  242.         var th = this.h;
  243.         if (a==null || (tw==null && th==null)) return;
  244.  
  245.         // anchoring/docking
  246.         var fn=dynapi.functions;
  247.         var padX=0,padY=0;
  248.         if(a.topA) {
  249.                 anc=fn.getAnchorLocation(a.topA,this);
  250.                 if(anc){padY=anc.y; th=th-padY;}
  251.         }
  252.         if(a.leftA) {
  253.                 anc=(a.leftA==a.topA && anc)? anc:fn.getAnchorLocation(a.leftA,this);
  254.                 if(anc) {padX=anc.x; tw=tw-padX;}
  255.         }
  256.         if(a.bottomA) {
  257.                 anc=fn.getAnchorLocation(a.bottomA,this);
  258.                 th=th-(this.h-anc.y);
  259.         }
  260.         if(a.rightA) {
  261.                 anc=(a.bottomA==a.rightA && anc)? anc:fn.getAnchorLocation(a.rightA,this);
  262.                 if(anc) tw=tw-(this.w-anc.x);
  263.         }
  264.  
  265.         var aleft=(tw>0 && a.left && typeof(a.left)=='string')? tw*(parseInt(a.left)/100):a.left;
  266.         var aright=(tw>0 && a.right && typeof(a.right)=='string')? tw*(parseInt(a.right)/100):a.right;
  267.         var atop=(th>0 && a.top && typeof(a.top)=='string')? th*(parseInt(a.top)/100):a.top;
  268.         var abottom=(th>0 && a.bottom && typeof(a.bottom)=='string')? th*(parseInt(a.bottom)/100):a.bottom;
  269.         var x = aleft;
  270.         var y = atop;
  271.         var w = null;
  272.         var h = null;
  273.         var dlyrWidth=dlyr.getWidth();
  274.         var dlyrHeight=dlyr.getHeight();
  275.         if (a.stretchH!=null) {
  276.                 if(typeof(a.stretchH)!='string') w=a.stretchH;
  277.                 else {
  278.                         if(a.stretchH=='*') w = tw - ((aleft!=null)? aleft:0);
  279.                         else w = tw*(parseInt(a.stretchH)/100);
  280.                 }
  281.                 dlyrWidth=w;
  282.         }
  283.         if (a.centerH!=null) {
  284.                 x = Math.ceil(tw/2 - dlyrWidth/2 + a.centerH);
  285.         }else if (aright!=null) {
  286.                 if (aleft!=null) w = (tw - aright) - aleft;
  287.                 else x = (tw - dlyrWidth) - aright;
  288.                 if(tw<=0 && x<0) x=null; // ns4 needs x>=0
  289.         }
  290.         if (a.stretchV!=null) {
  291.                 if(typeof(a.stretchV)!='string') h=a.stretchV;
  292.                 else {
  293.                         if(a.stretchV=='*') h = th - ((atop!=null)? atop:0);
  294.                         else h = th*(parseInt(a.stretchV)/100);
  295.                 }
  296.                 dlyrHeight=h;
  297.         }
  298.         if (a.centerV!=null) {
  299.                 y = Math.ceil(th/2 - dlyrHeight/2 + a.centerV);
  300.         }else if (abottom!=null) {
  301.                 if (atop!=null) h = (th - abottom) - atop;
  302.                 else y = (th - dlyrHeight) - abottom;
  303.                 if(th<=0 && y<0) y=null; // ns4 needs y>=0
  304.         }
  305.         if(padX) {x=(x)? x:0;x+=padX}
  306.         if(padY) {y=(y)? y:0;y+=padY}
  307.  
  308.         var tmp=dlyr._hasAnchor;
  309.         dlyr._hasAnchor=false; // ignore anchor updates of this layer
  310.         if(x!=null||y!=null) dlyr.setLocation(x,y);
  311.         if(w!=null||h!=null) dlyr.setSize(w,h);
  312.         dlyr._hasAnchor = tmp; // useful for preventing stack overflow
  313. };
  314. protoEvent._updateAnchors = function() {
  315.         var tw = this.w;
  316.         var th = this.h;
  317.         if (tw==null && th==null) return;
  318.         //console.log("[dynapi3x] _updateAnchor | THIS is a "+ this.getClassName());
  319.         // 'this' doit etre un sous-type de DynObject a priori
  320.  
  321.         var anchors_ids = Object.keys(this._childAnchors);
  322.         for (i = 0; i < anchors_ids.length; i++) {
  323.                 id = anchors_ids[i];
  324.                 this._updateAnchor(id);
  325.         }
  326.  
  327. };
  328.  
  329. // Bandwidth timer stop
  330. var ua=dynapi.ua; ua._bwe=new Date;
  331. ua.broadband=((ua._bwe-ua._bws)<=1500)? true:false;
  332.