source: trunk/spip/esqueleto-redcta/plugins/widget_calendar/img_pack/dom.js @ 133

Last change on this file since 133 was 30, checked in by sebas, 17 years ago

nueva importacion del codigo del esqueleto de redcta con los plugins

File size: 13.6 KB
Line 
1/*
2Copyright (c) 2006 Spip! Inc. All rights reserved.
3version 0.9.0
4*/
5
6/**
7 * @class Provides helper methods for DOM elements.
8 */
9SPIP.util.Dom = new function() {
10
11   /**
12    * Returns an HTMLElement reference
13    * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
14    * @return {HTMLElement} A DOM reference to an HTML element.
15    */
16   this.get = function(el) {
17      if (typeof el == 'string') { // accept object or id
18         el = document.getElementById(el);
19      }
20
21      return el;
22   };
23
24   /**
25    * Normalizes currentStyle and ComputedStyle.
26    * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
27    * @param {String} property The style property whose value is returned.
28    * @return {String} The current value of the style property.
29    */
30   this.getStyle = function(el, property) {
31      var value = null;
32      var dv = document.defaultView;
33
34      el = this.get(el);
35
36      if (property == 'opacity' && el.filters) {// IE opacity
37         value = 1;
38         try {
39            value = el.filters.item('DXImageTransform.Microsoft.Alpha').opacity / 100;
40         } catch(e) {
41            try {
42               value = el.filters.item('alpha').opacity / 100;
43            } catch(e) {}
44         }
45      }
46      else if (el.style[property]) {
47         value = el.style[property];
48      }
49      else if (el.currentStyle && el.currentStyle[property]) {
50         value = el.currentStyle[property];
51      }
52      else if ( dv && dv.getComputedStyle )
53      {  // convert camelCase to hyphen-case
54
55         var converted = '';
56         for(i = 0, len = property.length;i < len; ++i) {
57            if (property.charAt(i) == property.charAt(i).toUpperCase()) {
58               converted = converted + '-' + property.charAt(i).toLowerCase();
59            } else {
60               converted = converted + property.charAt(i);
61            }
62         }
63
64         if (dv.getComputedStyle(el, '').getPropertyValue(converted)) {
65            value = dv.getComputedStyle(el, '').getPropertyValue(converted);
66         }
67      }
68
69      return value;
70   };
71
72   /**
73    * Wrapper for setting style properties of HTMLElements.  Normalizes "opacity" across modern browsers.
74    * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
75    * @param {String} property The style property to be set.
76    * @param {String} val The value to apply to the given property.
77    */
78   this.setStyle = function(el, property, val) {
79      el = this.get(el);
80      switch(property) {
81         case 'opacity' :
82            if (el.filters) {
83               el.style.filter = 'alpha(opacity=' + val * 100 + ')';
84
85               if (!el.currentStyle.hasLayout) {
86                  el.style.zoom = 1;
87               }
88            } else {
89               el.style.opacity = val;
90               el.style['-moz-opacity'] = val;
91               el.style['-khtml-opacity'] = val;
92            }
93            break;
94         default :
95            el.style[property] = val;
96      }
97   };
98
99   /**
100    * Gets the current position of an element based on page coordinates.  Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
101    * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
102    */
103   this.getXY = function(el) {
104      el = this.get(el);
105
106      // has to be part of document to have pageXY
107      if (el.parentNode === null || this.getStyle(el, 'display') == 'none') {
108         return false;
109      }
110
111      /**
112       * Position of the html element (x, y)
113       * @private
114       * @type Array
115       */
116      var parent = null;
117      var pos = [];
118      var box;
119
120      if (el.getBoundingClientRect) { // IE
121         box = el.getBoundingClientRect();
122         var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
123         var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
124
125         return [box.left + scrollLeft, box.top + scrollTop];
126      }
127      else if (document.getBoxObjectFor) { // gecko
128         box = document.getBoxObjectFor(el);
129         pos = [box.x, box.y];
130      }
131      else { // safari/opera
132         pos = [el.offsetLeft, el.offsetTop];
133         parent = el.offsetParent;
134         if (parent != el) {
135            while (parent) {
136               pos[0] += parent.offsetLeft;
137               pos[1] += parent.offsetTop;
138               parent = parent.offsetParent;
139            }
140         }
141
142         // opera & (safari absolute) incorrectly account for body offsetTop
143         var ua = navigator.userAgent.toLowerCase();
144         if (
145            ua.indexOf('opera') != -1
146            || ( ua.indexOf('safari') != -1 && this.getStyle(el, 'position') == 'absolute' )
147         ) {
148            pos[1] -= document.body.offsetTop;
149         }
150      }
151
152      if (el.parentNode) { parent = el.parentNode; }
153      else { parent = null; }
154
155      while (parent && parent.tagName != 'BODY' && parent.tagName != 'HTML') {
156         pos[0] -= parent.scrollLeft;
157         pos[1] -= parent.scrollTop;
158
159         if (parent.parentNode) { parent = parent.parentNode; }
160         else { parent = null; }
161      }
162
163      return pos;
164   };
165
166   /**
167    * Gets the current X position of an element based on page coordinates.  The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
168    * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
169    */
170   this.getX = function(el) {
171      return this.getXY(el)[0];
172   };
173
174   /**
175    * Gets the current Y position of an element based on page coordinates.  Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
176    * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
177    */
178   this.getY = function(el) {
179      return this.getXY(el)[1];
180   };
181
182   /**
183    * Set the position of an html element in page coordinates, regardless of how the element is positioned.
184    * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
185    * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
186    * @param {array} pos Contains X & Y values for new position (coordinates are page-based)
187    */
188   this.setXY = function(el, pos, noRetry) {
189      el = this.get(el);
190      var pageXY = SPIP.util.Dom.getXY(el);
191      if (pageXY === false) { return false; } // has to be part of doc to have pageXY
192
193      if (this.getStyle(el, 'position') == 'static') { // default to relative
194         this.setStyle(el, 'position', 'relative');
195      }
196
197      var delta = [
198         parseInt( SPIP.util.Dom.getStyle(el, 'left'), 10 ),
199         parseInt( SPIP.util.Dom.getStyle(el, 'top'), 10 )
200      ];
201
202      if ( isNaN(delta[0]) ) { delta[0] = 0; } // defalts to 'auto'
203      if ( isNaN(delta[1]) ) { delta[1] = 0; }
204
205      if (pos[0] !== null) { el.style.left = pos[0] - pageXY[0] + delta[0] + 'px'; }
206      if (pos[1] !== null) { el.style.top = pos[1] - pageXY[1] + delta[1] + 'px'; }
207
208      var newXY = this.getXY(el);
209
210      // if retry is true, try one more time if we miss
211      if (!noRetry && (newXY[0] != pos[0] || newXY[1] != pos[1]) ) {
212         this.setXY(el, pos, true);
213      }
214
215      return true;
216   };
217
218   /**
219    * Set the X position of an html element in page coordinates, regardless of how the element is positioned.
220    * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
221    * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
222    * @param {Int} x to use as the X coordinate.
223    */
224   this.setX = function(el, x) {
225      return this.setXY(el, [x, null]);
226   };
227
228   /**
229    * Set the Y position of an html element in page coordinates, regardless of how the element is positioned.
230    * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
231    * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
232    * @param {Int} Value to use as the Y coordinate.
233    */
234   this.setY = function(el, y) {
235      return this.setXY(el, [null, y]);
236   };
237
238   /**
239    * Returns the region position of the given element.
240    * The element must be part of the DOM tree to have a region (display:none or elements not appended return false).
241    * @param {String | HTMLElement} Accepts either a string to use as an ID for getting a DOM reference, or an actual DOM reference.
242    * @return {Region} A Region instance containing "top, left, bottom, right" member data.
243    */
244   this.getRegion = function(el) {
245      el = this.get(el);
246      return new SPIP.util.Region.getRegion(el);
247   };
248
249   /**
250    * Returns the width of the client (viewport).
251    * @return {Int} The width of the viewable area of the page.
252    */
253   this.getClientWidth = function() {
254      return (
255         document.documentElement.offsetWidth
256         || document.body.offsetWidth
257      );
258   };
259
260   /**
261    * Returns the height of the client (viewport).
262    * @return {Int} The height of the viewable area of the page.
263    */
264   this.getClientHeight = function() {
265      return (
266         self.innerHeight
267         || document.documentElement.clientHeight
268         || document.body.clientHeight
269      );
270   };
271};
272
273/**
274 * @class A region is a representation of an object on a grid.  It is defined
275 * by the top, right, bottom, left extents, so is rectangular by default.  If
276 * other shapes are required, this class could be extended to support it.
277 *
278 * @param {int} t the top extent
279 * @param {int} r the right extent
280 * @param {int} b the bottom extent
281 * @param {int} l the left extent
282 * @constructor
283 */
284SPIP.util.Region = function(t, r, b, l) {
285
286    /**
287     * The region's top extent
288     * @type int
289     */
290    this.top = t;
291
292    /**
293     * The region's right extent
294     * @type int
295     */
296    this.right = r;
297
298    /**
299     * The region's bottom extent
300     * @type int
301     */
302    this.bottom = b;
303
304    /**
305     * The region's left extent
306     * @type int
307     */
308    this.left = l;
309};
310
311/**
312 * Returns true if this region contains the region passed in
313 *
314 * @param  {Region}  region The region to evaluate
315 * @return {boolean}        True if the region is contained with this region,
316 *                          else false
317 */
318SPIP.util.Region.prototype.contains = function(region) {
319    return ( region.left   >= this.left   &&
320             region.right  <= this.right  &&
321             region.top    >= this.top    &&
322             region.bottom <= this.bottom    );
323};
324
325/**
326 * Returns the area of the region
327 *
328 * @return {int} the region's area
329 */
330SPIP.util.Region.prototype.getArea = function() {
331    return ( (this.bottom - this.top) * (this.right - this.left) );
332};
333
334/**
335 * Returns the region where the passed in region overlaps with this one
336 *
337 * @param  {Region} region The region that intersects
338 * @return {Region}        The overlap region, or null if there is no overlap
339 */
340SPIP.util.Region.prototype.intersect = function(region) {
341    var t = Math.max( this.top,    region.top    );
342    var r = Math.min( this.right,  region.right  );
343    var b = Math.min( this.bottom, region.bottom );
344    var l = Math.max( this.left,   region.left   );
345
346    if (b >= t && r >= l) {
347        return new SPIP.util.Region(t, r, b, l);
348    } else {
349        return null;
350    }
351};
352
353/**
354 * Returns the region representing the smallest region that can contain both
355 * the passed in region and this region.
356 *
357 * @param  {Region} region The region that to create the union with
358 * @return {Region}        The union region
359 */
360SPIP.util.Region.prototype.union = function(region) {
361    var t = Math.min( this.top,    region.top    );
362    var r = Math.max( this.right,  region.right  );
363    var b = Math.max( this.bottom, region.bottom );
364    var l = Math.min( this.left,   region.left   );
365
366    return new SPIP.util.Region(t, r, b, l);
367};
368
369/**
370 * toString
371 * @return string the region properties
372 */
373SPIP.util.Region.prototype.toString = function() {
374    return ( "Region {" +
375             "  t: "    + this.top    +
376             ", r: "    + this.right  +
377             ", b: "    + this.bottom +
378             ", l: "    + this.left   +
379             "}" );
380}
381
382/**
383 * Returns a region that is occupied by the DOM element
384 *
385 * @param  {HTMLElement} el The element
386 * @return {Region}         The region that the element occupies
387 * @static
388 */
389SPIP.util.Region.getRegion = function(el) {
390    var p = SPIP.util.Dom.getXY(el);
391
392    var t = p[1];
393    var r = p[0] + el.offsetWidth;
394    var b = p[1] + el.offsetHeight;
395    var l = p[0];
396
397    return new SPIP.util.Region(t, r, b, l);
398};
399
400/////////////////////////////////////////////////////////////////////////////
401
402
403/**
404 * @class
405 *
406 * A point is a region that is special in that it represents a single point on
407 * the grid.
408 *
409 * @param {int} x The X position of the point
410 * @param {int} y The Y position of the point
411 * @constructor
412 * @extends Region
413 */
414SPIP.util.Point = function(x, y) {
415    /**
416     * The X position of the point
417     * @type int
418     */
419    this.x      = x;
420
421    /**
422     * The Y position of the point
423     * @type int
424     */
425    this.y      = y;
426
427    this.top    = y;
428    this.right  = x;
429    this.bottom = y;
430    this.left   = x;
431};
432
433SPIP.util.Point.prototype = new SPIP.util.Region();
Note: See TracBrowser for help on using the repository browser.