rsence-pre 2.2.0.37 → 2.2.0.38

Sign up to get free protection for your applications and to get access to all the features.
data/js/core/elem/elem.js DELETED
@@ -1,1321 +0,0 @@
1
- /* RSence
2
- * Copyright 2007 Riassence Inc.
3
- * http://riassence.com/
4
- *
5
- * You should have received a copy of the GNU General Public License along
6
- * with this software package. If not, contact licensing@riassence.com
7
- */
8
-
9
- /** = Description
10
- * An object that contains the browser types detected as booleans.
11
- **/
12
- var//RSence.Core
13
- BROWSER_TYPE = {
14
-
15
- /* Any browser on Mac OS X */
16
- mac: false,
17
-
18
- /* Any browser on Windows */
19
- win: false,
20
-
21
- /* Any version of Microsoft Internet Explorer */
22
- ie: false,
23
-
24
- /* Microsoft Internet Explorer version 6 */
25
- ie6: false,
26
-
27
- /* Microsoft Internet Explorer version 7 */
28
- ie7: false,
29
-
30
- /* Microsoft Internet Explorer version 8 */
31
- ie8: false,
32
-
33
- /* Microsoft Internet Explorer version 9 */
34
- ie9: false,
35
-
36
- /* Any version of Opera */
37
- opera: false,
38
-
39
- /* Any version of Safari (and other KHTML/WebKit -derived browsers) */
40
- safari: false,
41
-
42
- /* The Symbian version of KHTML/WebKit/Safari, is also registered as +safari+ */
43
- symbian: false,
44
-
45
- /* Any version of Google Chrome, is also registered as +safari+ */
46
- chrome: false,
47
-
48
- /* Any version of Mozilla Firefox */
49
- firefox: false,
50
-
51
- /* Mozilla Firefox version 2 */
52
- firefox2: false,
53
-
54
- /* Mozilla Firefox version 3 */
55
- firefox3: false,
56
-
57
- /* Mozilla Firefox version 4 */
58
- firefox4: false
59
- };
60
-
61
- /** = Description
62
- * The DOM Abstraction collection. Implements a managed buffer
63
- * for style properties.
64
- **/
65
- var//RSence.Core
66
- ELEM = {
67
-
68
- /** = Description
69
- * The interval to flush the buffer specified in milliseconds.
70
- * Defaults to 60fps which is the most common refresh rate of displays.
71
- **/
72
- // ELEMTickerInterval: 16.667,
73
- ELEMTickerInterval: 33,
74
-
75
- // stuff moved inside this function, because (surprise, surprise!) ie6 had some issues with it.
76
- _constructor: function() {
77
- var _this = ELEM;
78
-
79
- // pre-init queue
80
- _this._domLoadQueue = [];
81
- _this._domLoadTimer = null;
82
-
83
- // turns true when document is actually loaded:
84
- _this._domLoadStatus = false;
85
-
86
- // initial tasks
87
-
88
- _this._flushTime = 0;
89
- _this._flushCounter = 0;
90
- _this._idleDelay = 500;
91
-
92
- _this._timer = null;
93
- _this._minDelay = _this.ELEMTickerInterval;
94
- _this._flushing = false;
95
- _this._needFlush = false;
96
- _this._slowness = 1;
97
-
98
- _this._elements = [];
99
- _this._freeElemIds = [];
100
- _this._styleCache = {};
101
- _this._styleTodo = {};
102
- _this._attrTodo = {};
103
- _this._attrCache = {};
104
- _this._elemTodo = [];
105
- _this._elemTodoH = {};
106
- _this._blockElems = ",ADDRESS,BLOCKQUOTE,CENTER,DIR,DIV,DL,FIELDSET,FORM,H1,H2,H3,H4,H5,H6,HR,ISINDEX,MENU,NOFRAMES,NOSCRIPT,OL,P,PRE,TABLE,UL,";
107
- },
108
-
109
- // adds an element reference
110
- // returns its id
111
- _add: function(_elem) {
112
- var
113
- _id,
114
- _this = ELEM,
115
- _elements = _this._elements,
116
- _hasFreeElemIds = (_this._freeElemIds.length !== 0);
117
- if (_hasFreeElemIds) {
118
- _id = _this._freeElemIds.pop();
119
- _elements[_id] = _elem;
120
- }
121
- else {
122
- // Adds the element to the cache
123
- _elements.push(_elem);
124
- // Get cache size == serial id
125
- _id = _elements.length - 1;
126
- }
127
- return _id;
128
- },
129
-
130
- // makes new style caches
131
- _initCache: function(_id) {
132
- var _this = ELEM;
133
- _this._styleTodo[_id] = [];
134
- _this._styleCache[_id] = {};
135
- _this._attrTodo[_id] = [];
136
- _this._attrCache[_id] = {};
137
- _this._elemTodoH[_id] = false;
138
- },
139
-
140
- /** = Description
141
- * Binds a DOM element by the DOM ID-attribute.
142
- *
143
- * = Parameters
144
- * +_domId+:: The element's ID-attribute to bind.
145
- *
146
- * = Returns
147
- * The ELEM ID (to use with other ELEM methods.
148
- *
149
- **/
150
- bindId: function(_domId) {
151
- var
152
- _this = ELEM,
153
- _elem = document.getElementById(_domId),
154
- _elemId = _this._add(_elem);
155
- _this._initCache(_elemId);
156
- return _elemId;
157
- },
158
-
159
- /** = Description
160
- * Binds a DOM element by the DOM Element Object itself.
161
- *
162
- * = Parameters
163
- * +_elem+:: The DOM Element object to bind.
164
- *
165
- * = Returns
166
- * The ELEM ID (to use with other ELEM methods.
167
- *
168
- **/
169
- bind: function(_elem) {
170
- var
171
- _this = ELEM,
172
- _id = _this._add(_elem);
173
- _this._initCache(_id);
174
- return _id;
175
- },
176
-
177
- // deprecated; backwards-compatibility
178
- _replace: function(_id, _elem) {
179
- ELEM._elements[_id] = _elem;
180
- },
181
-
182
- /** = Description
183
- * Gets a DOM Element by its ELEM ID.
184
- *
185
- * = Parameters
186
- * +_id+:: The ELEM ID.
187
- *
188
- * = Returns
189
- * The DOM Element object.
190
- *
191
- **/
192
- get: function(_id) {
193
- return ELEM._elements[_id];
194
- },
195
-
196
- /** = Description
197
- * Sets the innerHTML of an element by its ELEM ID.
198
- *
199
- * = Parameters
200
- * +_id+:: The ELEM ID.
201
- * +_html+:: The HTML Block as a string to set the innerHTMl property with.
202
- *
203
- **/
204
- setHTML: function(_id, _html) {
205
- try {
206
- var _this = ELEM, _elem = _this._elements[_id];
207
- if (!_elem) {
208
- return;
209
- }
210
- if (! ((typeof _html === 'string') || (typeof _html === 'number'))) {
211
- return;
212
- }
213
- if (_elem.innerHTML !== _html ){
214
- _elem.innerHTML = _html;
215
- }
216
- } catch(e) {}
217
- //_this._initCache(_id);
218
- },
219
-
220
- /** = Description
221
- * Gets the innerHTML of an element by its ELEM ID.
222
- *
223
- * = Parameters
224
- * +_id+:: The ELEM ID.
225
- *
226
- * = Returns
227
- * The innerHTML of the element the ELEM ID is bound to.
228
- *
229
- **/
230
- getHTML: function(_id) {
231
- try {
232
- var _this = ELEM;
233
- if (_this._elements[_id]) {
234
- return _this._elements[_id].innerHTML;
235
- }
236
- } catch(e) {}
237
- //_this._initCache(_id);
238
- return '';
239
- },
240
-
241
- /** = Description
242
- * Deletes an element and its associated buffers by ELEM ID.
243
- *
244
- * = Parameters
245
- * +_id+:: The ELEM Id to delete.
246
- *
247
- **/
248
- del: function(_id) {
249
- var
250
- _this = ELEM,
251
- _elem = _this._elements[_id];
252
- // if (_this._flushing) {
253
- // console.log('warn: already flushin.. retrying delete');
254
- // setTimeout( function(){_this.del(_id)}, 10 );
255
- // }
256
- // _this._flushing = true;
257
- var _elemTodoIdx = _this._elemTodo.indexOf(_id);
258
- if (_elemTodoIdx !== -1) {
259
- _this._elemTodo.splice(_elemTodoIdx, 1);
260
- }
261
- _this._initCache(_id);
262
- _this._freeElemIds.push(_id);
263
- var _parentNode = _elem.parentNode;
264
- if (_parentNode !== null) {
265
- _parentNode.removeChild(_elem);
266
- }
267
- _elem = null;
268
- _this._elements[_id] = null;
269
- // _this._flushing = false;
270
- },
271
-
272
- /** = Description
273
- * Moves the source element inside the target element.
274
- *
275
- * = Parameters
276
- * +_sourceId+:: The source element's ELEM ID to move.
277
- * +_targetId+:: The target element's ELEM ID to move the source element into.
278
- *
279
- **/
280
- append: function(_sourceId, _targetId) {
281
- var
282
- _this = ELEM,
283
- _source = _this._elements[_sourceId],
284
- _target = _this._elements[_targetId];
285
- _target.appendChild(_source);
286
- },
287
-
288
- /** = Description
289
- * Replaces all styles of the element with the string containing css source.
290
- *
291
- * = Parameters
292
- * +_id+:: The ELEM ID which all styles will be replaced
293
- * with the css source.
294
- * +_cssText+:: A string containing the CSS Text.
295
- *
296
- **/
297
- setCSS: function(_id, _cssText) {
298
- ELEM._elements[_id].style.cssText = _cssText;
299
- },
300
-
301
- /** = Description
302
- * Returns the CSS source style of the element.
303
- *
304
- * = Parameters
305
- * +_id+:: The ELEM ID which all styles will be returned as
306
- * a string containing the CSS source.
307
- *
308
- * = Returns
309
- * A string containing the CSS source of the element.
310
- *
311
- **/
312
- getCSS: function(_id) {
313
- return ELEM._elements[_id].style.cssText;
314
- },
315
-
316
- /** = Description
317
- * Returns the visible size of an element.
318
- *
319
- * = Parameters
320
- * +_id+:: The ELEM ID.
321
- *
322
- * = Returns
323
- * An [ width, height ] pair as an Array.
324
- *
325
- **/
326
- getVisibleSize: function(_id) {
327
- var
328
- _parentOverflow,
329
- _this = ELEM,
330
- _elem = _this._elements[_id],
331
- w = _elem.offsetWidth,
332
- h = _elem.offsetHeight,
333
- _parent = _elem.parentNode;
334
- while (_parent && _parent.nodeName.toLowerCase() !== 'body') {
335
- _this._getComputedStyle( _parent, 'overflow' );
336
- _parentOverflow = _parentOverflow !== 'visible';
337
- if (w > _parent.clientWidth && _parentOverflow) {
338
- w = _parent.clientWidth - _elem.offsetLeft;
339
- }
340
- if (h > _parent.clientHeight && _parentOverflow) {
341
- h = _parent.clientHeight - _elem.offsetTop;
342
- }
343
- _elem = _elem.parentNode;
344
- _parent = _elem.parentNode;
345
- }
346
- return [w, h];
347
- },
348
-
349
- /** = Description
350
- * Returns the full size of the element.
351
- *
352
- * = Parameters
353
- * +_id+:: The ELEM ID.
354
- *
355
- * = Returns
356
- * An [ width, height ] pair as an Array.
357
- *
358
- **/
359
- getSize: function(_id) {
360
- var
361
- _this = ELEM,
362
- _elem = _this._elements[_id],
363
- w = _elem.offsetWidth,
364
- h = _elem.offsetHeight;
365
- return [w, h];
366
- },
367
-
368
- /** = Description
369
- * Returns the scroll size of the element.
370
- *
371
- * = Parameters
372
- * +_id+:: The ELEM ID.
373
- *
374
- * = Returns
375
- * An [ width, height ] pair as an Array.
376
- *
377
- **/
378
- getScrollSize: function(_id) {
379
- var
380
- _this = ELEM,
381
- _elem = _this._elements[_id],
382
- w = _elem.scrollWidth,
383
- h = _elem.scrollHeight;
384
- return [w, h];
385
- },
386
-
387
- _getVisibleLeftPosition: function(_id){
388
- var
389
- _this = ELEM,
390
- x = 0,
391
- _elem = _this._elements[_id];
392
- while (_elem !== document) {
393
- x += _elem.offsetLeft;
394
- x -= _elem.scrollLeft;
395
- _elem = _elem.parentNode;
396
- if (!_elem) {
397
- break;
398
- }
399
- }
400
- return x;
401
- },
402
-
403
- _getVisibleTopPosition: function(_id){
404
- var
405
- _this = ELEM,
406
- y = 0,
407
- _elem = _this._elements[_id];
408
- while (_elem !== document) {
409
- y += _elem.offsetTop;
410
- y -= _elem.scrollTop;
411
- _elem = _elem.parentNode;
412
- if (!_elem) {
413
- break;
414
- }
415
- }
416
- return y;
417
- },
418
-
419
- /** = Description
420
- * Returns the real position of the element, subtracting whatever
421
- * scroll bars do to the position..
422
- *
423
- * = Parameters
424
- * +_id+:: The ELEM ID.
425
- *
426
- * = Returns
427
- * An [ x, y ] coordinate pair as an Array.
428
- *
429
- **/
430
- getVisiblePosition: function(_id) {
431
- var _this = ELEM;
432
- return [
433
- _this._getVisibleLeftPosition(_id),
434
- _this._getVisibleTopPosition(_id)
435
- ];
436
- },
437
-
438
- /** = Description
439
- * Returns the opacity of the element.
440
- *
441
- * = Parameters
442
- * +_id+:: The ELEM ID.
443
- *
444
- * = Returns
445
- * The opacity as a floating point number between 0.0 (transparent) and 1.0 (opaque).
446
- *
447
- **/
448
- getOpacity: function(_id) {
449
- var
450
- _this = ELEM,
451
- _elem = _this.get(_id),
452
- _opacity = _this._getComputedStyle( _elem, 'opacity' );
453
- if (ELEM.ie && (_elem.currentStyle['filter'] || '').match(/alpha(opacity=(.*))/)) {
454
- if (_opacity[1]) {
455
- return parseFloat(_opacity[1]) / 100;
456
- }
457
- return 1;
458
- }
459
- else {
460
- return parseFloat(_opacity);
461
- }
462
- return 1.0;
463
- },
464
-
465
- /** = Description
466
- * Sets the opacity of the element.
467
- *
468
- * = Parameters
469
- * +_id+:: The ELEM ID.
470
- * +_opacity+:: The opacity as a floating point number between 0.0 (transparent) and 1.0 (opaque).
471
- *
472
- **/
473
- setOpacity: function(_id, _opacity) {
474
- var _this = ELEM;
475
- if (_opacity === 1 && (BROWSER_TYPE.ie6 || BROWSER_TYPE.ie7 || BROWSER_TYPE.ie8)) {
476
- _this._elements[_id].style.setAttribute('filter', _this.getStyle(_id, 'filter', true).replace(/alpha([^)]*)/gi, ''));
477
- }
478
- else {
479
- if (_opacity < 0.01) {
480
- _opacity = 0;
481
- }
482
- if (BROWSER_TYPE.ie6 || BROWSER_TYPE.ie7 || BROWSER_TYPE.ie8) {
483
- var _prevAlpha = _this.getStyle(_id, 'filter', true);
484
- _this._elements[_id].style.setAttribute('filter', _prevAlpha.replace(/alpha([^)]*)/gi, '') + 'alpha(opacity=' + _opacity * 100 + ')');
485
- }
486
- else {
487
- _this._elements[_id].style.setProperty('opacity', _opacity, '');
488
- }
489
- }
490
- },
491
-
492
- /** = Description
493
- * Like getStyle, but always return an integer number.
494
- *
495
- * = Parameters
496
- * +_id+:: The ELEM ID.
497
- * +_key+:: The style property name.
498
- *
499
- * = Returns
500
- * The value of the style property.
501
- *
502
- **/
503
- getIntStyle: function(_id, _key) {
504
- return parseInt(ELEM.getStyle(_id, _key), 10);
505
- },
506
-
507
- /** = Description
508
- * Sets the box coordinates (x,y,width,height) all at once.
509
- *
510
- * = Parameters
511
- * +_id+:: The ELEM ID.
512
- * +_coords+:: An array containing exactly four coordinates in the following
513
- * order: x, y, width, height
514
- *
515
- **/
516
- setBoxCoords: function(_id, _coords) {
517
- ELEM.setStyle(_id, 'left', _coords[0] + 'px');
518
- ELEM.setStyle(_id, 'top', _coords[1] + 'px');
519
- ELEM.setStyle(_id, 'width', _coords[2] + 'px');
520
- ELEM.setStyle(_id, 'height', _coords[3] + 'px');
521
- },
522
-
523
- _getExtraLeftWidth: function(_id){
524
- var _int = ELEM.getIntStyle;
525
- return _int(_id, 'padding-left') + _int(_id, 'border-left-width');
526
- },
527
-
528
- _getExtraRightWidth: function(_id){
529
- var _int = ELEM.getIntStyle;
530
- return _int(_id, 'padding-right') + _int(_id, 'border-right-width');
531
- },
532
-
533
- /** = Description
534
- * Returns the amount of width of the element taken by 'extra' space: border
535
- * and padding size.
536
- *
537
- * = Parameters
538
- * +_id+:: The ELEM ID.
539
- *
540
- * = Returns
541
- * The amount of extra width as an integer.
542
- *
543
- **/
544
- getExtraWidth: function(_id) {
545
- var _this = ELEM;
546
- return _this._getExtraLeftWidth(_id) + _this._getExtraRightWidth(_id);
547
- },
548
-
549
- _getExtraTopWidth: function(_id){
550
- var _int = ELEM.getIntStyle;
551
- return _int(_id, 'padding-top') + _int(_id, 'border-top-width');
552
- },
553
-
554
- _getExtraBottomWidth: function(_id){
555
- var _int = ELEM.getIntStyle;
556
- return _int(_id, 'padding-bottom') + _int(_id, 'border-bottom-width');
557
- },
558
-
559
- /** = Description
560
- * Returns the amount of height of the element taken by 'extra' space: border
561
- * and padding size.
562
- *
563
- * = Parameters
564
- * +_id+:: The ELEM ID.
565
- *
566
- * = Returns
567
- * The amount of extra height as an integer.
568
- *
569
- **/
570
- getExtraHeight: function(_id) {
571
- var _this = ELEM;
572
- return _this._getExtraTopWidth(_id) + _this._getExtraBottomWidth(_id);
573
- },
574
-
575
- /** = Description
576
- * Re-calculates the amount of delay to achieve a new target frame rate.
577
- *
578
- * The DOM refreshes are typically the most expensive tasks of an Javascript
579
- * application, it's a good idea to set an optimal frame rate for the DOM
580
- * updates to let your logic code get as many cpu cycles as possible without
581
- * wasting most of them on more DOM refreshes than necessary.
582
- *
583
- * The default frame rate is 30 and the maximum frame rate allowed is 100.
584
- *
585
- * = Parameters
586
- * +_fps+:: The target frame rate (DOM updates per second).
587
- *
588
- **/
589
- setFPS: function(_fps) {
590
- var _this = ELEM;
591
- _this._minDelay = 1000 / _fps;
592
- if (_this._minDelay < _this.ELEMTickerInterval) {
593
- _this._minDelay = _this.ELEMTickerInterval;
594
- }
595
- },
596
-
597
- /** = Description
598
- * An additional adjustment multiplier to offset the slowness of a
599
- * target browser.
600
- *
601
- * The default is 1.0 (no change to the flush delay calculated by setFPS)
602
- * A higher value than 1.0 means less frequent updates (slower than
603
- * target machine).
604
- *
605
- * You'll need a benchmark in your application to calculate the multiplier
606
- * correctly depending on the tasks necessary. The multiplier is useless
607
- * without a benchmark, unless you want to temporarily make updates very
608
- * infrequent (or frequent) depending on what your application needs to do.
609
- *
610
- * = Parameters
611
- * +_slowness+:: The multiplier used to offset the DOM update delay.
612
- *
613
- **/
614
- setSlowness: function(_slowness) {
615
- // we should replace this with an
616
- // actual browser speed benchmark
617
- ELEM._slowness = _slowness;
618
- },
619
-
620
- /** = Description
621
- * Sets the idle delay.
622
- *
623
- * The idle delay is the amount of milliseconds between polling for something
624
- * to flush to DOM. This is the setting affecting how long (max) it takes to
625
- * start flushing the buffers after the buffers have been emptied.
626
- *
627
- * = Parameters
628
- * +_idleDelay+:: The amount of milliseconds to wait before re-checking
629
- * the buffers after going idle.
630
- *
631
- **/
632
- setIdleDelay: function(_idleDelay) {
633
- ELEM._idleDelay = _idleDelay;
634
- },
635
-
636
- // flag for IE6
637
- _ieFixesNeeded: false,
638
-
639
- /** = Description
640
- * Flushes the buffers.
641
- * Call this method manually, if you need to ensure all changes are
642
- * flushed to the DOM before doing another operation.
643
- *
644
- * = Parameters:
645
- * +_delay+:: Time (ms) before retrying, if another flushLoop is busy.
646
- *
647
- **/
648
- flushLoop: function(_delay) {
649
- var
650
- _this = ELEM;
651
- if (BROWSER_TYPE.ie6 && _this._ieFixesNeeded) {
652
- iefix._traverseTree();
653
- _this._ieFixesNeeded = false;
654
- }
655
- clearTimeout(_this._timer);
656
- if (_this._flushing) {
657
- _delay *= 2;
658
- _this._timer = setTimeout(
659
- function(){
660
- ELEM.flushLoop( _delay );
661
- }, _delay
662
- );
663
- return;
664
- }
665
- else {
666
- if (!_this._needFlush) {
667
- // goto sleep mode
668
- if (BROWSER_TYPE.ie6 && _this._ieFixesNeeded) {
669
- iefix._traverseTree();
670
- _this._ieFixesNeeded = false;
671
- }
672
- _this._timer = setTimeout(
673
- function(){
674
- ELEM.flushLoop(_delay);
675
- }, _this._idleDelay
676
- );
677
- return;
678
- }
679
- _delay = Math.round(_this._slowness * (_this._flushTime / _this._flushCounter), _this.ELEMTickerInterval);
680
- if (_delay < _this._minDelay || !_delay) {
681
- _delay = _this._minDelay;
682
- }
683
- _this._flushing = true;
684
- _this._timer = setTimeout(
685
- function(){
686
- ELEM.flushLoop(_delay);
687
- }, _delay
688
- );
689
- }
690
- _this._flushTime -= new Date().getTime();
691
- var
692
- i = 0,
693
- _id,
694
- _elemTodo = _this._elemTodo,
695
- _loopMaxL = _elemTodo.length,
696
- _currTodo = _elemTodo.splice(0, _loopMaxL),
697
- _flushStartTime = new Date().getTime();
698
- for (; i < _loopMaxL; i++) {
699
- _this._flushLoopFlushed++;
700
- _id = _currTodo.pop();
701
- _this._elemTodoH[_id] = false;
702
- _this._flushStyleCache(_id);
703
- _this._flushAttrCache(_id);
704
- }
705
- _this._flushCounter++;
706
- _this._flushTime += new Date().getTime();
707
- if (_this._elemTodo.length === 0 && _this._needFlush) {
708
- _this._needFlush = false;
709
- }
710
- _this._flushing = false;
711
- },
712
-
713
- /* Method for flushing the attribute cache */
714
- _flushAttrCache: function(_id) {
715
- var
716
- _this = ELEM,
717
- _attrTodo = _this._attrTodo[_id],
718
- _attrCache = _this._attrCache[_id],
719
- _elem = _this._elements[_id],
720
- //_elemP=_elem.setAttribute,
721
- _key,
722
- _val,
723
- i,
724
- _iMax = _attrTodo.length,
725
- _currTodo = _attrTodo.splice(0, _iMax);
726
- for (i = 0; i !== _iMax; i++) {
727
- _key = _currTodo.pop();
728
- _val = _attrCache[_key];
729
- _elem.setAttribute(_key, _val);
730
- }
731
- },
732
-
733
- /** = Description
734
- * Gets a named element attribute.
735
- *
736
- * Regular element attributes are cached like the style attributes.
737
- * Use this method to get an attribute from the element.
738
- *
739
- * = Parameters
740
- * +_id+:: The ELEM ID.
741
- * +_key+:: The Attribute name.
742
- * +_bypass+:: A flag used to bypass the buffers (Optional, default: false)
743
- *
744
- * = Returns
745
- * The attribute value.
746
- *
747
- **/
748
- getAttr: function(_id, _key, _bypass) {
749
- var
750
- _this = ELEM,
751
- _attrVal = _this._attrCache[_id][_key],
752
- _val;
753
- if (_attrVal !== undefined && !_bypass) {
754
- return _attrVal;
755
- }
756
- var
757
- _elem = _this._elements[_id];
758
- if (_elem.getAttribute(_key) === null) {
759
- _elem[_key] = '';
760
- }
761
- _val = _elem.getAttribute(_key);
762
- _this._attrCache[_id][_key] = _val;
763
- return _val;
764
- },
765
-
766
- /** = Description
767
- * Sets a named element attribute value.
768
- *
769
- * Regular element attributes are cached like the style attributes.
770
- * Use this method to set an attribute value to the element.
771
- *
772
- * = Parameters
773
- * +_id+:: The ELEM ID.
774
- * +_key+:: The Attribute name.
775
- * +_value+:: The Attribute value.
776
- * +_bypass+:: A flag used to bypass the buffers (Optional, default: false)
777
- *
778
- **/
779
- setAttr: function(_id, _key, _value, _bypass) {
780
- var
781
- _this = ELEM,
782
- _attrTodo = _this._attrTodo[_id],
783
- _attrCache = _this._attrCache[_id],
784
- _differs = _value !== _this.getAttr(_id, _key);
785
- if (_differs || _bypass) {
786
- _attrCache[_key] = _value;
787
- if (_bypass) {
788
- _this._elements[_id].setAttribute(_key, _value);
789
- }
790
- else {
791
- if (_attrTodo.indexOf(_key) === -1) {
792
- _attrTodo.push(_key);
793
- }
794
- if (!_this._elemTodoH[_id]) {
795
- _this._elemTodo.push(_id);
796
- _this._elemTodoH[_id] = true;
797
- _this._checkNeedFlush();
798
- }
799
- }
800
- }
801
- },
802
-
803
- /** = Description
804
- * Deletes a named element attribute
805
- *
806
- * = Parameters
807
- * +_id+:: The ELEM ID.
808
- * +_key+:: The Attribute name.
809
- *
810
- **/
811
- delAttr: function(_id, _key) {
812
- var
813
- _differs,
814
- _this = ELEM,
815
- _attrTodo = _this._attrTodo[_id],
816
- _attrCache = _this._attrCache[_id];
817
- delete _attrCache[_key];
818
- _this._elements[_id].removeAttribute(_key);
819
- if (_attrTodo.indexOf(_key) !== -1) {
820
- _attrTodo.splice(_attrTodo.indexOf(_key, 1));
821
- }
822
- if (_this._elemTodoH[_id]) {
823
- _this._elemTodo.splice(_this._elemTodo.indexOf(_id),1);
824
- _this._elemTodoH[_id] = false;
825
- _this._checkNeedFlush();
826
- }
827
- },
828
-
829
- /** = Description
830
- * Checks if a element has a CSS class name.
831
- *
832
- * = Parameters
833
- * +_elemId+:: The ELEM ID.
834
- * +_className+:: The CSS class name to check.
835
- *
836
- * = Returns
837
- * Returns null, if the element does not exist
838
- * Returns true, if the element has the class name set
839
- * Returns false otherwise
840
- *
841
- **/
842
- hasClassName: function(_elemId, _className) {
843
- var
844
- _elem = ELEM.get(_elemId);
845
- if (!_elem) {
846
- return null;
847
- }
848
- var
849
- _classNames = _elem.className.split(' ');
850
- return (_classNames.indexOf(_className) !== -1);
851
- },
852
-
853
- /** = Description
854
- * Adds a CSS class name to the element.
855
- *
856
- * = Parameters
857
- * +_elemId+:: The ELEM ID.
858
- * +_className+:: The CSS class name to add.
859
- *
860
- **/
861
- addClassName: function(_elemId, _className) {
862
- var _this = ELEM,
863
- _element = _this.get(_elemId);
864
- if (!_element) {
865
- return;
866
- }
867
-
868
- if(_element.className === '' || _element.className === ' '){
869
- _element.className = _className;
870
- }
871
- else{
872
- var _classNames = _element.className.split(' '),
873
- _index = _classNames.indexOf(_className);
874
- if(_index===-1){
875
- _classNames.push(_className);
876
- _element.className = _classNames.join(' ');
877
- }
878
- }
879
- },
880
-
881
- /** = Description
882
- * Removes the CSS class name from the element.
883
- *
884
- * = Parameters
885
- * +_elemId+:: The ELEM ID.
886
- * +_className+:: The CSS class name to remove.
887
- *
888
- **/
889
- removeClassName: function(_elemId, _className) {
890
- var _this = ELEM,
891
- _element = _this.get(_elemId);
892
- if (!_element) {
893
- return;
894
- }
895
-
896
- if(!_this.hasClassName(_elemId, _className)){
897
- return;
898
- }
899
-
900
- var _classNames = _element.className.split(' '),
901
- _index = _classNames.indexOf(_className);
902
- if(_index!==-1){
903
- _classNames.splice(_index,1);
904
- _element.className = _classNames.join(' ');
905
- }
906
- },
907
-
908
- /* Checks, if the buffers need to be flushed. */
909
- _checkNeedFlush: function() {
910
- var _this = ELEM;
911
- if (!_this._needFlush) {
912
- _this._needFlush = true;
913
- if (!_this._flushing) {
914
- clearTimeout(_this._timer);
915
- _this._timer = setTimeout( function(){ELEM.flushLoop(ELEM._minDelay);}, _this._minDelay);
916
- }
917
- }
918
- },
919
-
920
- _setElementStyle: function(_elem,_key,_value){
921
- _elem.style.setProperty(_key, _value, '');
922
- },
923
- _setElementStyleIE: function(_elem,_key,_value){
924
- var
925
- _this = ELEM,
926
- _camelKey = _key.replace(
927
- /((-)([a-z])(\w))/g,
928
- function($0, $1, $2, $3, $4) {
929
- return $3.toUpperCase() + $4;
930
- }
931
- );
932
- _elem.style[_camelKey] = _value;
933
- if (BROWSER_TYPE.ie6) {
934
- if (iefix._traverseStyleProperties.indexOf(_key) !== -1) {
935
- _this._ieFixesNeeded = true;
936
- }
937
- }
938
- },
939
-
940
- /** = Description
941
- * Sets the named element style attribute value.
942
- *
943
- * Use this method to set a style attribute value optimally.
944
- * Element style attributes are buffered.
945
- * The buffers are flushed on regular intervals.
946
- *
947
- * = Parameters
948
- * +_id+:: The ELEM ID.
949
- * +_key+:: The Style Attribute name.
950
- * +_value+:: The Style Attribute value.
951
- * +_bypass+:: A flag used to bypass the buffers (Optional, default: false)
952
- *
953
- **/
954
- setStyle: function(_id, _key, _value, _bypass) {
955
- if( BROWSER_TYPE.ie9 ){ _bypass = true; }
956
- var
957
- _this = ELEM,
958
- _cached = _this._styleCache[_id],
959
- _elems = _this._elements,
960
- _differs;
961
- if (_cached === undefined) {
962
- _this._initCache(_id);
963
- _cached = _this._styleCache[_id];
964
- }
965
- _differs = _value !== _cached[_key];
966
- if (_differs) {
967
- _cached[_key] = _value;
968
- if (_bypass) {
969
- if (_key === 'opacity') {
970
- _this.setOpacity(_id, _value);
971
- }
972
- else if ( !_elems[_id] ){
973
- console.log('ELEM#setStyle: Not a element! id:',_id,', key:',_key,', value:', _value);
974
- }
975
- else {
976
- _this._setElementStyle( _elems[_id], _key, _cached[_key] );
977
- }
978
- }
979
- else {
980
- var
981
- _elemTodoH = _this._elemTodoH,
982
- _styleTodo = _this._styleTodo[_id];
983
- if (_styleTodo.indexOf(_key) === -1) {
984
- _styleTodo.push(_key);
985
- }
986
- if (!_elemTodoH[_id]) {
987
- _this._elemTodo.push(_id);
988
- _elemTodoH[_id] = true;
989
- _this._checkNeedFlush();
990
- }
991
- }
992
- }
993
- },
994
-
995
- /** = Description
996
- * Creates a new element inside another.
997
- *
998
- * Use this method to create a new DOM element.
999
- *
1000
- * = Parameters
1001
- * +_targetId+:: The ELEM ID of the parent element.
1002
- * (Optional, default: 0; the document body)
1003
- *
1004
- * +_tagName+:: The tag name of the element.
1005
- * (Optional, default: 'DIV')
1006
- *
1007
- * +_options+:: Options to set before appending child to parent.
1008
- * Supported option attrs: [[key,value],[key,value]]
1009
- * (Optional, rarely necessary except when creating IMG tags)
1010
- *
1011
- * = Returns
1012
- * The new ELEM ID.
1013
- *
1014
- **/
1015
- make: function(_targetId, _tagName, _options) {
1016
- if (_targetId === undefined) {
1017
- _targetId = 0;
1018
- }
1019
- if (_tagName === undefined) {
1020
- _tagName = 'DIV';
1021
- }
1022
- else {
1023
- _tagName = _tagName.toUpperCase();
1024
- }
1025
- var _this = ELEM,
1026
- _elem,
1027
- _id;
1028
- _elem = document.createElement(_tagName);
1029
- _id = _this._add(_elem);
1030
- _this._initCache(_id);
1031
- if(_options!==undefined){
1032
- if(_options.attrs){
1033
- var
1034
- i = 0,
1035
- _key, _value;
1036
- for( ; i<_options.attrs.length; i++ ){
1037
- _key = _options.attrs[i][0];
1038
- _value = _options.attrs[i][1];
1039
- _elem[_key] = _value;
1040
- _this.setAttr( _id, _key, _value );
1041
- }
1042
- }
1043
- }
1044
- _this._elements[_targetId].appendChild(_elem);
1045
- return _id;
1046
- },
1047
-
1048
- /** = Description
1049
- * Returns the inner size of the browser window.
1050
- *
1051
- * = Returns
1052
- * An [ width, height ] pair as an Array.
1053
- *
1054
- **/
1055
- windowSize: function() {
1056
- return [
1057
- (window.innerWidth) ? window.innerWidth: document.documentElement.clientWidth,
1058
- (window.innerHeight) ? window.innerHeight: document.documentElement.clientHeight
1059
- ];
1060
- },
1061
-
1062
- _getComputedStyle: function(_elem,_key){
1063
- return document.defaultView.getComputedStyle(_elem,null).getPropertyValue(_key);
1064
- },
1065
- _getComputedStyleIE: function(_elem,_key){
1066
- if(_key === 'width'){
1067
- return _elem.clientWidth+'px';
1068
- }
1069
- if(_key === 'height'){
1070
- return _elem.clientHeight+'px';
1071
- }
1072
- var _camelName = _key.replace(
1073
- /((-)([a-z])(\w))/g,
1074
- function($0, $1, $2, $3, $4) {
1075
- return $3.toUpperCase() + $4;
1076
- }
1077
- );
1078
- return _elem.currentStyle[_camelName];
1079
- },
1080
-
1081
- /** = Description
1082
- * Gets the named element style attribute value.
1083
- *
1084
- * Use this method to get a style attribute value optimally.
1085
- * Element style attributes are buffered.
1086
- *
1087
- * = Parameters
1088
- * +_id+:: The ELEM ID.
1089
- * +_key+:: The Style Attribute name.
1090
- * +_bypass+:: A flag used to bypass the buffers (Optional, default: false)
1091
- *
1092
- * = Returns
1093
- * The element style attribute value.
1094
- *
1095
- **/
1096
- getStyle: function(_id, _key, _bypass){
1097
- var
1098
- _this=ELEM,
1099
- _cached=_this._styleCache[_id],
1100
- _retval;
1101
- if ((_cached[_key] === undefined) || _bypass) {
1102
- if ((_key === 'opacity') && _bypass) {
1103
- _retval = _this.getOpacity(_id);
1104
- }
1105
- else {
1106
- _retval = _this._getComputedStyle(_this._elements[_id],_key);
1107
- if(_key === 'z-index' && _retval === 'auto'){
1108
- _retval = -1;
1109
- }
1110
- }
1111
- _cached[_key] = _retval;
1112
- }
1113
- else {
1114
- if(_key === 'z-index'){
1115
- console.log('cached:',_cached[_key]);
1116
- }
1117
- }
1118
- return _cached[_key];
1119
- },
1120
-
1121
- /* Style buffer flushing algorithm */
1122
- _flushStyleCache: function(_id) {
1123
- var
1124
- _this = ELEM,
1125
- _styleTodo = _this._styleTodo[_id],
1126
- _cached = _this._styleCache[_id],
1127
- _elem = _this._elements[_id],
1128
- _elemS,
1129
- _loopMaxP,
1130
- _cid,
1131
- _key,
1132
- _currTodo,
1133
- _retval;
1134
- if (!_elem) {
1135
- return;
1136
- }
1137
- _loopMaxP = _styleTodo.length;
1138
- _currTodo = _styleTodo.splice(0, _loopMaxP);
1139
- for (_cid = 0; _cid !== _loopMaxP; _cid++) {
1140
- _key = _currTodo.pop();
1141
- if (_key === 'opacity') {
1142
- _this.setOpacity(_id, _cached[_key]);
1143
- }
1144
- else if ( !_elem ){
1145
- console.log('ELEM#_flushStyleCache: Not a element! id:',_id,', key:',_key,', value:', _value);
1146
- }
1147
- else {
1148
- _this._setElementStyle( _elem, _key, _cached[_key] );
1149
- }
1150
- }
1151
- },
1152
-
1153
- /* The ELEM "post-constructor" */
1154
- _init: function() {
1155
- if(RSenceInit !== undefined){
1156
- RSenceInit();
1157
- }
1158
-
1159
- var _this = ELEM;
1160
-
1161
- if (BROWSER_TYPE.ie) {
1162
- _this._getComputedStyle = _this._getComputedStyleIE;
1163
- _this._setElementStyle = _this._setElementStyleIE;
1164
- }
1165
-
1166
- if(!_this['_timer']){
1167
- _this.bind(document.body);
1168
- }
1169
-
1170
- if(BROWSER_TYPE.symbian){
1171
- var TestClass = HClass.extend({
1172
- test: true,
1173
- constructor: null
1174
- });
1175
- // Symbian dies in the loop when loading itself cached on reload, restart loop by re-calling this function in 1 second.
1176
- if(!TestClass.test){
1177
- var _gotoOpera = confirm('Your Web Browser fails. Please restart the S60 Web Browser or install a better browser.\nDo you want to download and install Opera Mobile now?');
1178
- if(_gotoOpera){
1179
- location.href = 'http://www.opera.com/download/get.pl?sub=++++&id=32792&location=270&nothanks=yes';
1180
- }
1181
- // Can't do anything without proper JS support.
1182
- return;
1183
- }
1184
- }
1185
- _this._flushDomLoadQueueBusy = false;
1186
- while(!ELEM._initDone){
1187
- ELEM._flushDomLoadQueue();
1188
- }
1189
- _this._timer = setTimeout( function(){ if(!ELEM._flushDomLoadQueueBusy){ELEM.flushLoop(ELEM._minDelay); }}, ELEM._minDelay );
1190
- },
1191
-
1192
- _flushDomLoadQueue: function(){
1193
- var _cmd,
1194
- _type,
1195
- _cmdResult;
1196
- if(ELEM._domLoadQueue.length === 0){
1197
- ELEM._initDone = true;
1198
- }
1199
- else {
1200
- _cmd = ELEM._domLoadQueue.shift();
1201
- _type = (typeof _cmd);
1202
- if (_type === 'function') {
1203
- _cmd.call();
1204
- }
1205
- else if (_type === 'string') {
1206
- _cmdResult = eval(_cmd);
1207
- if (typeof _cmdResult === 'string') {
1208
- ELEM._domLoadQueue.push(_cmdResult);
1209
- }
1210
- }
1211
- }
1212
- },
1213
-
1214
- /* Checks browser versions and starts the document load check */
1215
- _warmup: function() {
1216
- var
1217
- _this = ELEM,
1218
- _ua = navigator.userAgent,
1219
- _isIE = (document.all && (_ua.indexOf("Opera") === -1)),
1220
- _browserType = BROWSER_TYPE;
1221
- _browserType.opera = _ua.indexOf("Opera") !== -1;
1222
- _browserType.safari = _ua.indexOf("KHTML") !== -1;
1223
- _browserType.symbian = _ua.indexOf("SymbianOS") !== -1;
1224
- _browserType.chrome = _ua.indexOf("Chrome") !== -1;
1225
- _browserType.ie = _isIE;
1226
- _browserType.ie6 = _isIE && (_ua.indexOf("MSIE 6") !== -1);
1227
- _browserType.ie7 = _isIE && (_ua.indexOf("MSIE 7") !== -1);
1228
- _browserType.ie8 = _isIE && (_ua.indexOf("MSIE 8") !== -1);
1229
- _browserType.ie9 = _isIE && (_ua.indexOf("MSIE 9") !== -1);
1230
-
1231
- _browserType.mac = (_ua.indexOf("Macintosh") !== -1);
1232
- _browserType.win = (_ua.indexOf("Windows") !== -1);
1233
-
1234
- _browserType.firefox = _ua.indexOf("Firefox") !== -1;
1235
- _browserType.firefox2 = _ua.indexOf("Firefox/2.") !== -1;
1236
- _browserType.firefox3 = _ua.indexOf("Firefox/3.") !== -1;
1237
- _browserType.firefox4 = _ua.indexOf("Firefox/4.") !== -1;
1238
- _this._domWaiter();
1239
- },
1240
-
1241
- /* Adds commands to be run when the document load check turns true */
1242
- _domLoader: function(_cmd) {
1243
- var _type = (typeof _cmd);
1244
- if (ELEM._initDone === true) {
1245
- if( _type === 'string' ) {
1246
- eval(_cmd);
1247
- }
1248
- else if (_type === 'function'){
1249
- _cmd.call();
1250
- }
1251
- }
1252
- else {
1253
- ELEM._domLoadQueue.push(_cmd);
1254
- }
1255
- },
1256
-
1257
- /* Checks if the document is fully loaded */
1258
- _domWaiter: function() {
1259
- var _isloaded = false,
1260
- _this = ELEM;
1261
- // A hack for ie (ripped from DomLoaded.js)
1262
- // http://www.cherny.com/demos/onload/domloaded.js
1263
- if (BROWSER_TYPE.ie && !BROWSER_TYPE.ie9) {
1264
- var _ie_proto = "javascript:void(0)";
1265
- if (location.protocol === "https:") {
1266
- _ie_proto = "src=//0";
1267
- }
1268
- document.write("<scr" + "ipt id=__ie_onload defer src=" + _ie_proto + "></scr" + "ipt>");
1269
- var _ie_script = document.getElementById("__ie_onload");
1270
- _ie_script.onreadystatechange = function() {
1271
- if ((this.readyState === "complete") && true) {
1272
- clearTimeout(_this._domLoadTimer);
1273
- _this._domLoadStatus = true;
1274
- _this._init();
1275
- }
1276
- };
1277
- // the event will trigger on ie, so we don't have to keep on polling:
1278
- return;
1279
- }
1280
-
1281
- // Safari / KHTML readyness detection:
1282
- else if (BROWSER_TYPE.safari && document.readyState === 'complete'){
1283
- // (/loaded|complete/.test(document.readyState))) {
1284
- // (/loaded|complete/.test(document.readyState))) {
1285
- _this._domLoadStatus = true;
1286
- }
1287
-
1288
- // Works for Mozilla:
1289
- else if (document.body) {
1290
- _this._domLoadStatus = true;
1291
- }
1292
-
1293
- if (_this._domLoadStatus) {
1294
- clearTimeout(_this._domLoadTimer);
1295
- if(BROWSER_TYPE.symbian){
1296
- /*
1297
- document.body.innerHTML produces beyond-wtf "fastinnerhtml!", maybe they "fixed" an unit test?
1298
- see: http://trac.webkit.org/browser/S60/trunk/WebCore/khtml/html/html_elementimpl.cpp#L750
1299
- */
1300
-
1301
- /* This check ensures we are use actually testing the beyond buggy S60 Web Browser.
1302
- Better versions are handled like regular safari/webkit/chrome/khtml
1303
- */
1304
- BROWSER_TYPE.symbian = document.body.innerHTML === "fastinnerhtml!";
1305
- }
1306
- _this._init();
1307
- }
1308
- else {
1309
- _this._domLoadTimer = setTimeout(_this._domWaiter, 10 ); // (_this.ELEMTickerInterval * 10));
1310
- }
1311
- }
1312
- };
1313
- ELEM._constructor();
1314
-
1315
- var//RSence.Foundation
1316
- ElementManager = ELEM;
1317
-
1318
- var//RSence.Core
1319
- LOAD = ELEM._domLoader;
1320
-
1321
- ELEM._warmup();