imba-source 0.14.1 → 0.14.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3997 +0,0 @@
1
- (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.imba = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2
- (function(){
3
-
4
- if (typeof Imba === 'undefined') {
5
- require('./imba');
6
-
7
- Imba.CLIENT = true;
8
-
9
- require('./core.events');
10
- require('./scheduler');
11
- require('./tag');
12
- require('./dom');
13
- require('./dom.client');
14
- require('./dom.html');
15
- require('./dom.svg');
16
- require('./dom.legacy');
17
- require('./dom.events');
18
- require('./dom.static');
19
- return require('./selector');
20
- } else {
21
- return console.warn("Imba is already loaded");
22
- };
23
-
24
- })()
25
- },{"./core.events":2,"./dom":6,"./dom.client":3,"./dom.events":4,"./dom.html":5,"./dom.legacy":7,"./dom.static":8,"./dom.svg":9,"./imba":10,"./scheduler":11,"./selector":12,"./tag":13}],2:[function(require,module,exports){
26
- (function(){
27
-
28
-
29
- function emit__(event,args,node){
30
- // var node = cbs[event]
31
- var prev,cb,ret;
32
-
33
- while ((prev = node) && (node = node.next)){
34
- if (cb = node.listener) {
35
- if (node.path && cb[node.path]) {
36
- ret = args ? (cb[node.path].apply(cb,args)) : (cb[node.path]());
37
- } else {
38
- // check if it is a method?
39
- ret = args ? (cb.apply(node,args)) : (cb.call(node));
40
- };
41
- };
42
-
43
- if (node.times && --node.times <= 0) {
44
- prev.next = node.next;
45
- node.listener = null;
46
- };
47
- };
48
- return;
49
- };
50
-
51
- // method for registering a listener on object
52
- Imba.listen = function (obj,event,listener,path){
53
- var $1;
54
- var cbs,list,tail;
55
- cbs = obj.__listeners__ || (obj.__listeners__ = {});
56
- list = cbs[($1 = event)] || (cbs[$1] = {});
57
- tail = list.tail || (list.tail = (list.next = {}));
58
- tail.listener = listener;
59
- tail.path = path;
60
- list.tail = tail.next = {};
61
- return tail;
62
- };
63
-
64
- Imba.once = function (obj,event,listener){
65
- var tail = Imba.listen(obj,event,listener);
66
- tail.times = 1;
67
- return tail;
68
- };
69
-
70
- Imba.unlisten = function (obj,event,cb,meth){
71
- var node,prev;
72
- var meta = obj.__listeners__;
73
- if (!meta) { return };
74
-
75
- if (node = meta[event]) {
76
- while ((prev = node) && (node = node.next)){
77
- if (node == cb || node.listener == cb) {
78
- prev.next = node.next;
79
- // check for correct path as well?
80
- node.listener = null;
81
- break;
82
- };
83
- };
84
- };
85
- return;
86
- };
87
-
88
- Imba.emit = function (obj,event,params){
89
- var cb;
90
- if (cb = obj.__listeners__) {
91
- if (cb[event]) { emit__(event,params,cb[event]) };
92
- if (cb.all) { emit__(event,[event,params],cb.all) }; // and event != 'all'
93
- };
94
- return;
95
- };
96
-
97
- return Imba.observeProperty = function (observer,key,trigger,target,prev){
98
- if (prev && typeof prev == 'object') {
99
- Imba.unlisten(prev,'all',observer,trigger);
100
- };
101
- if (target && typeof target == 'object') {
102
- Imba.listen(target,'all',observer,trigger);
103
- };
104
- return this;
105
- };
106
-
107
- })()
108
- },{}],3:[function(require,module,exports){
109
- (function(){
110
- function iter$(a){ return a ? (a.toArray ? a.toArray() : a) : []; };
111
- // Extending Imba.Tag#css to work without prefixes by inspecting
112
- // the properties of a CSSStyleDeclaration and creating a map
113
-
114
- // var prefixes = ['-webkit-','-ms-','-moz-','-o-','-blink-']
115
- // var props = ['transform','transition','animation']
116
-
117
- var styles = window.getComputedStyle(document.documentElement,'');
118
-
119
- Imba.CSSKeyMap = {};
120
-
121
- for (var i = 0, ary = iter$(styles), len = ary.length, prefixed; i < len; i++) {
122
- prefixed = ary[i];
123
- var unprefixed = prefixed.replace(/^-(webkit|ms|moz|o|blink)-/,'');
124
- var camelCase = unprefixed.replace(/-(\w)/g,function(m,a) { return a.toUpperCase(); });
125
-
126
- // if there exists an unprefixed version -- always use this
127
- if (prefixed != unprefixed) {
128
- if (styles.hasOwnProperty(unprefixed)) { continue; };
129
- };
130
-
131
- // register the prefixes
132
- Imba.CSSKeyMap[unprefixed] = Imba.CSSKeyMap[camelCase] = prefixed;
133
- };
134
-
135
- return tag$.extendTag('htmlelement', function(tag){
136
-
137
- // override the original css method
138
- tag.prototype.css = function (key,val){
139
- if (key instanceof Object) {
140
- for (var i = 0, keys = Object.keys(key), l = keys.length; i < l; i++){
141
- this.css(keys[i],key[keys[i]]);
142
- };
143
- return this;
144
- };
145
-
146
- key = Imba.CSSKeyMap[key] || key;
147
-
148
- if (val == null) {
149
- this.dom().style.removeProperty(key);
150
- } else if (val == undefined) {
151
- return this.dom().style[key];
152
- } else {
153
- if ((typeof val=='number'||val instanceof Number) && key.match(/width|height|left|right|top|bottom/)) {
154
- val = val + "px";
155
- };
156
- this.dom().style[key] = val;
157
- };
158
- return this;
159
- };
160
- });
161
-
162
- })()
163
- },{}],4:[function(require,module,exports){
164
- (function(){
165
- function iter$(a){ return a ? (a.toArray ? a.toArray() : a) : []; };
166
- var doc = document;
167
- var win = window;
168
-
169
- var hasTouchEvents = window && window.ontouchstart !== undefined;
170
-
171
- Imba.Pointer = function Pointer(){
172
- this.setButton(-1);
173
- this.setEvent({x: 0,y: 0,type: 'uninitialized'});
174
- return this;
175
- };
176
-
177
-
178
-
179
- Imba.Pointer.prototype.phase = function(v){ return this._phase; }
180
- Imba.Pointer.prototype.setPhase = function(v){ this._phase = v; return this; };
181
-
182
-
183
- Imba.Pointer.prototype.prevEvent = function(v){ return this._prevEvent; }
184
- Imba.Pointer.prototype.setPrevEvent = function(v){ this._prevEvent = v; return this; };
185
-
186
-
187
- Imba.Pointer.prototype.button = function(v){ return this._button; }
188
- Imba.Pointer.prototype.setButton = function(v){ this._button = v; return this; };
189
-
190
-
191
- Imba.Pointer.prototype.event = function(v){ return this._event; }
192
- Imba.Pointer.prototype.setEvent = function(v){ this._event = v; return this; };
193
-
194
-
195
- Imba.Pointer.prototype.dirty = function(v){ return this._dirty; }
196
- Imba.Pointer.prototype.setDirty = function(v){ this._dirty = v; return this; };
197
-
198
-
199
- Imba.Pointer.prototype.events = function(v){ return this._events; }
200
- Imba.Pointer.prototype.setEvents = function(v){ this._events = v; return this; };
201
-
202
-
203
- Imba.Pointer.prototype.touch = function(v){ return this._touch; }
204
- Imba.Pointer.prototype.setTouch = function(v){ this._touch = v; return this; };
205
-
206
- Imba.Pointer.prototype.update = function (e){
207
- this.setEvent(e);
208
- this.setDirty(true);
209
- return this;
210
- };
211
-
212
- // this is just for regular mouse now
213
- Imba.Pointer.prototype.process = function (){
214
- var e1 = this.event();
215
-
216
- if (this.dirty()) {
217
- this.setPrevEvent(e1);
218
- this.setDirty(false);
219
-
220
- // button should only change on mousedown etc
221
- if (e1.type == 'mousedown') {
222
- this.setButton(e1.button);
223
-
224
- // do not create touch for right click
225
- if (this.button() == 2 || (this.touch() && this.button() != 0)) {
226
- return;
227
- };
228
-
229
- // cancel the previous touch
230
- if (this.touch()) { this.touch().cancel() };
231
- this.setTouch(new Imba.Touch(e1,this));
232
- this.touch().mousedown(e1,e1);
233
- } else if (e1.type == 'mousemove') {
234
- if (this.touch()) { this.touch().mousemove(e1,e1) };
235
- } else if (e1.type == 'mouseup') {
236
- this.setButton(-1);
237
-
238
- if (this.touch() && this.touch().button() == e1.button) {
239
- this.touch().mouseup(e1,e1);
240
- this.setTouch(null);
241
- };
242
- // trigger pointerup
243
- };
244
- } else {
245
- if (this.touch()) { this.touch().idle() };
246
- };
247
- return this;
248
- };
249
-
250
- Imba.Pointer.prototype.cleanup = function (){
251
- return Imba.POINTERS;
252
- };
253
-
254
- Imba.Pointer.prototype.x = function (){
255
- return this.event().x;
256
- };
257
- Imba.Pointer.prototype.y = function (){
258
- return this.event().y;
259
- };
260
-
261
- // deprecated -- should remove
262
- Imba.Pointer.update = function (){
263
- // console.log('update touch')
264
- for (var i = 0, ary = iter$(Imba.POINTERS), len = ary.length; i < len; i++) {
265
- ary[i].process();
266
- };
267
- // need to be able to prevent the default behaviour of touch, no?
268
- win.requestAnimationFrame(Imba.Pointer.update);
269
- return this;
270
- };
271
-
272
- var lastNativeTouchTimeStamp = 0;
273
- var lastNativeTouchTimeout = 50;
274
-
275
- // Imba.Touch
276
- // Began A finger touched the screen.
277
- // Moved A finger moved on the screen.
278
- // Stationary A finger is touching the screen but hasn't moved.
279
- // Ended A finger was lifted from the screen. This is the final phase of a touch.
280
- // Canceled The system cancelled tracking for the touch.
281
-
282
- /*
283
- Consolidates mouse and touch events. Touch objects persist across a touch,
284
- from touchstart until end/cancel. When a touch starts, it will traverse
285
- down from the innermost target, until it finds a node that responds to
286
- ontouchstart. Unless the touch is explicitly redirected, the touch will
287
- call ontouchmove and ontouchend / ontouchcancel on the responder when appropriate.
288
-
289
- tag draggable
290
- # called when a touch starts
291
- def ontouchstart touch
292
- flag 'dragging'
293
- self
294
-
295
- # called when touch moves - same touch object
296
- def ontouchmove touch
297
- # move the node with touch
298
- css top: touch.dy, left: touch.dx
299
-
300
- # called when touch ends
301
- def ontouchend touch
302
- unflag 'dragging'
303
-
304
- @iname touch
305
- */
306
-
307
- Imba.Touch = function Touch(event,pointer){
308
- // @native = false
309
- this.setEvent(event);
310
- this.setData({});
311
- this.setActive(true);
312
- this._button = event && event.button || 0;
313
- this._suppress = false; // deprecated
314
- this._captured = false;
315
- this.setBubble(false);
316
- pointer = pointer;
317
- this.setUpdates(0);
318
- return this;
319
- };
320
-
321
- var touches = [];
322
- var count = 0;
323
- var identifiers = {};
324
-
325
- Imba.Touch.count = function (){
326
- return count;
327
- };
328
-
329
- Imba.Touch.lookup = function (item){
330
- return item && (item.__touch__ || identifiers[item.identifier]);
331
- };
332
-
333
- Imba.Touch.release = function (item,touch){
334
- var v_, $1;
335
- (((v_ = identifiers[item.identifier]),delete identifiers[item.identifier], v_));
336
- ((($1 = item.__touch__),delete item.__touch__, $1));
337
- return;
338
- };
339
-
340
- Imba.Touch.ontouchstart = function (e){
341
- for (var i = 0, ary = iter$(e.changedTouches), len = ary.length, t; i < len; i++) {
342
- t = ary[i];
343
- if (this.lookup(t)) { continue; };
344
- var touch = identifiers[t.identifier] = new this(e); // (e)
345
- t.__touch__ = touch;
346
- touches.push(touch);
347
- count++;
348
- touch.touchstart(e,t);
349
- };
350
- return this;
351
- };
352
-
353
- Imba.Touch.ontouchmove = function (e){
354
- var touch;
355
- for (var i = 0, ary = iter$(e.changedTouches), len = ary.length, t; i < len; i++) {
356
- t = ary[i];
357
- if (touch = this.lookup(t)) {
358
- touch.touchmove(e,t);
359
- };
360
- };
361
-
362
- return this;
363
- };
364
-
365
- Imba.Touch.ontouchend = function (e){
366
- var touch;
367
- for (var i = 0, ary = iter$(e.changedTouches), len = ary.length, t; i < len; i++) {
368
- t = ary[i];
369
- if (touch = this.lookup(t)) {
370
- touch.touchend(e,t);
371
- this.release(t,touch);
372
- count--;
373
- };
374
- };
375
-
376
- // e.preventDefault
377
- // not always supported!
378
- // touches = touches.filter(||)
379
- return this;
380
- };
381
-
382
- Imba.Touch.ontouchcancel = function (e){
383
- var touch;
384
- for (var i = 0, ary = iter$(e.changedTouches), len = ary.length, t; i < len; i++) {
385
- t = ary[i];
386
- if (touch = this.lookup(t)) {
387
- touch.touchcancel(e,t);
388
- this.release(t,touch);
389
- count--;
390
- };
391
- };
392
- return this;
393
- };
394
-
395
- Imba.Touch.onmousedown = function (e){
396
- return this;
397
- };
398
-
399
- Imba.Touch.onmousemove = function (e){
400
- return this;
401
- };
402
-
403
- Imba.Touch.onmouseup = function (e){
404
- return this;
405
- };
406
-
407
-
408
-
409
-
410
- Imba.Touch.prototype.phase = function(v){ return this._phase; }
411
- Imba.Touch.prototype.setPhase = function(v){ this._phase = v; return this; };
412
-
413
-
414
- Imba.Touch.prototype.active = function(v){ return this._active; }
415
- Imba.Touch.prototype.setActive = function(v){ this._active = v; return this; };
416
-
417
-
418
- Imba.Touch.prototype.event = function(v){ return this._event; }
419
- Imba.Touch.prototype.setEvent = function(v){ this._event = v; return this; };
420
-
421
-
422
- Imba.Touch.prototype.pointer = function(v){ return this._pointer; }
423
- Imba.Touch.prototype.setPointer = function(v){ this._pointer = v; return this; };
424
-
425
-
426
- Imba.Touch.prototype.target = function(v){ return this._target; }
427
- Imba.Touch.prototype.setTarget = function(v){ this._target = v; return this; };
428
-
429
-
430
- Imba.Touch.prototype.handler = function(v){ return this._handler; }
431
- Imba.Touch.prototype.setHandler = function(v){ this._handler = v; return this; };
432
-
433
-
434
- Imba.Touch.prototype.updates = function(v){ return this._updates; }
435
- Imba.Touch.prototype.setUpdates = function(v){ this._updates = v; return this; };
436
-
437
-
438
- Imba.Touch.prototype.suppress = function(v){ return this._suppress; }
439
- Imba.Touch.prototype.setSuppress = function(v){ this._suppress = v; return this; };
440
-
441
-
442
- Imba.Touch.prototype.data = function(v){ return this._data; }
443
- Imba.Touch.prototype.setData = function(v){ this._data = v; return this; };
444
-
445
- Imba.Touch.prototype.__bubble = {chainable: true,name: 'bubble'};
446
- Imba.Touch.prototype.bubble = function(v){ return v !== undefined ? (this.setBubble(v),this) : this._bubble; }
447
- Imba.Touch.prototype.setBubble = function(v){ this._bubble = v; return this; };
448
-
449
-
450
-
451
- Imba.Touch.prototype.gestures = function(v){ return this._gestures; }
452
- Imba.Touch.prototype.setGestures = function(v){ this._gestures = v; return this; };
453
-
454
- /*
455
-
456
-
457
- @internal
458
- @constructor
459
- */
460
-
461
- Imba.Touch.prototype.capture = function (){
462
- this._captured = true;
463
- this._event && this._event.preventDefault();
464
- return this;
465
- };
466
-
467
- Imba.Touch.prototype.isCaptured = function (){
468
- return !!this._captured;
469
- };
470
-
471
- /*
472
- Extend the touch with a plugin / gesture.
473
- All events (touchstart,move etc) for the touch
474
- will be triggered on the plugins in the order they
475
- are added.
476
- */
477
-
478
- Imba.Touch.prototype.extend = function (plugin){
479
- // console.log "added gesture!!!"
480
- this._gestures || (this._gestures = []);
481
- this._gestures.push(plugin);
482
- return this;
483
- };
484
-
485
- /*
486
- Redirect touch to specified target. ontouchstart will always be
487
- called on the new target.
488
- @return {Number}
489
- */
490
-
491
- Imba.Touch.prototype.redirect = function (target){
492
- this._redirect = target;
493
- return this;
494
- };
495
-
496
- /*
497
- Suppress the default behaviour. Will call preventDefault for
498
- all native events that are part of the touch.
499
- */
500
-
501
- Imba.Touch.prototype.suppress = function (){
502
- // collision with the suppress property
503
- this._active = false;
504
- return this;
505
- };
506
-
507
- Imba.Touch.prototype.setSuppress = function (value){
508
- console.warn('Imba.Touch#suppress= is deprecated');
509
- this._supress = value;
510
- return this;
511
- };
512
-
513
- Imba.Touch.prototype.touchstart = function (e,t){
514
- this._event = e;
515
- this._touch = t;
516
- this._button = 0;
517
- this._x = t.clientX;
518
- this._y = t.clientY;
519
- this.began();
520
- if (e && this.isCaptured()) { e.preventDefault() };
521
- return this;
522
- };
523
-
524
- Imba.Touch.prototype.touchmove = function (e,t){
525
- this._event = e;
526
- this._x = t.clientX;
527
- this._y = t.clientY;
528
- this.update();
529
- if (e && this.isCaptured()) { e.preventDefault() };
530
- return this;
531
- };
532
-
533
- Imba.Touch.prototype.touchend = function (e,t){
534
- this._event = e;
535
- this._x = t.clientX;
536
- this._y = t.clientY;
537
- this.ended();
538
-
539
- lastNativeTouchTimeStamp = e.timeStamp;
540
-
541
- if (this._maxdr < 20) {
542
- var tap = new Imba.Event(e);
543
- tap.setType('tap');
544
- tap.process();
545
- if (tap._responder) { e.preventDefault() };
546
- };
547
-
548
- if (e && this.isCaptured()) {
549
- e.preventDefault();
550
- };
551
-
552
- return this;
553
- };
554
-
555
- Imba.Touch.prototype.touchcancel = function (e,t){
556
- return this.cancel();
557
- };
558
-
559
- Imba.Touch.prototype.mousedown = function (e,t){
560
- var self = this;
561
- self._event = e;
562
- self._button = e.button;
563
- self._x = t.clientX;
564
- self._y = t.clientY;
565
- self.began();
566
-
567
- self._mousemove = function(e) { return self.mousemove(e,e); };
568
- doc.addEventListener('mousemove',self._mousemove,true);
569
- return self;
570
- };
571
-
572
- Imba.Touch.prototype.mousemove = function (e,t){
573
- this._x = t.clientX;
574
- this._y = t.clientY;
575
- this._event = e;
576
- if (this.isCaptured()) { e.preventDefault() };
577
- this.update();
578
- this.move();
579
- return this;
580
- };
581
-
582
- Imba.Touch.prototype.mouseup = function (e,t){
583
- this._x = t.clientX;
584
- this._y = t.clientY;
585
- this.ended();
586
- doc.removeEventListener('mousemove',this._mousemove,true);
587
- this._mousemove = null;
588
- return this;
589
- };
590
-
591
- Imba.Touch.prototype.idle = function (){
592
- return this.update();
593
- };
594
-
595
- Imba.Touch.prototype.began = function (){
596
- this._maxdr = this._dr = 0;
597
- this._x0 = this._x;
598
- this._y0 = this._y;
599
-
600
- var dom = this.event().target;
601
- var node = null;
602
-
603
- this._sourceTarget = dom && tag$wrap(dom);
604
-
605
- while (dom){
606
- node = tag$wrap(dom);
607
- if (node && node.ontouchstart) {
608
- this._bubble = false;
609
- this.setTarget(node);
610
- this.target().ontouchstart(this);
611
- if (!this._bubble) { break; };
612
- };
613
- dom = dom.parentNode;
614
- };
615
-
616
- this._updates++;
617
- return this;
618
- };
619
-
620
- Imba.Touch.prototype.update = function (){
621
- var target_;
622
- if (!this._active) { return this };
623
-
624
- var dr = Math.sqrt(this.dx() * this.dx() + this.dy() * this.dy());
625
- if (dr > this._dr) { this._maxdr = dr };
626
- this._dr = dr;
627
-
628
- // catching a touch-redirect?!?
629
- if (this._redirect) {
630
- if (this._target && this._target.ontouchcancel) {
631
- this._target.ontouchcancel(this);
632
- };
633
- this.setTarget(this._redirect);
634
- this._redirect = null;
635
- if (this.target().ontouchstart) { this.target().ontouchstart(this) };
636
- };
637
-
638
-
639
- this._updates++;
640
- if (this._gestures) {
641
- for (var i = 0, ary = iter$(this._gestures), len = ary.length; i < len; i++) {
642
- ary[i].ontouchupdate(this);
643
- };
644
- };
645
-
646
- (target_ = this.target()) && target_.ontouchupdate && target_.ontouchupdate(this);
647
- return this;
648
- };
649
-
650
- Imba.Touch.prototype.move = function (){
651
- var target_;
652
- if (!this._active) { return this };
653
-
654
- if (this._gestures) {
655
- for (var i = 0, ary = iter$(this._gestures), len = ary.length, g; i < len; i++) {
656
- g = ary[i];
657
- if (g.ontouchmove) { g.ontouchmove(this,this._event) };
658
- };
659
- };
660
-
661
- (target_ = this.target()) && target_.ontouchmove && target_.ontouchmove(this,this._event);
662
- return this;
663
- };
664
-
665
- Imba.Touch.prototype.ended = function (){
666
- var target_;
667
- if (!this._active) { return this };
668
-
669
- this._updates++;
670
-
671
- if (this._gestures) {
672
- for (var i = 0, ary = iter$(this._gestures), len = ary.length; i < len; i++) {
673
- ary[i].ontouchend(this);
674
- };
675
- };
676
-
677
- (target_ = this.target()) && target_.ontouchend && target_.ontouchend(this);
678
-
679
- return this;
680
- };
681
-
682
- Imba.Touch.prototype.cancel = function (){
683
- if (!this._cancelled) {
684
- this._cancelled = true;
685
- this.cancelled();
686
- if (this._mousemove) { doc.removeEventListener('mousemove',this._mousemove,true) };
687
- };
688
- return this;
689
- };
690
-
691
- Imba.Touch.prototype.cancelled = function (){
692
- var target_;
693
- if (!this._active) { return this };
694
-
695
- this._cancelled = true;
696
- this._updates++;
697
-
698
- if (this._gestures) {
699
- for (var i = 0, ary = iter$(this._gestures), len = ary.length, g; i < len; i++) {
700
- g = ary[i];
701
- if (g.ontouchcancel) { g.ontouchcancel(this) };
702
- };
703
- };
704
-
705
- (target_ = this.target()) && target_.ontouchcancel && target_.ontouchcancel(this);
706
- return this;
707
- };
708
-
709
- /*
710
- The absolute distance the touch has moved from starting position
711
- @return {Number}
712
- */
713
-
714
- Imba.Touch.prototype.dr = function (){
715
- return this._dr;
716
- };
717
-
718
- /*
719
- The distance the touch has moved horizontally
720
- @return {Number}
721
- */
722
-
723
- Imba.Touch.prototype.dx = function (){
724
- return this._x - this._x0;
725
- };
726
-
727
- /*
728
- The distance the touch has moved vertically
729
- @return {Number}
730
- */
731
-
732
- Imba.Touch.prototype.dy = function (){
733
- return this._y - this._y0;
734
- };
735
-
736
- /*
737
- Initial horizontal position of touch
738
- @return {Number}
739
- */
740
-
741
- Imba.Touch.prototype.x0 = function (){
742
- return this._x0;
743
- };
744
-
745
- /*
746
- Initial vertical position of touch
747
- @return {Number}
748
- */
749
-
750
- Imba.Touch.prototype.y0 = function (){
751
- return this._y0;
752
- };
753
-
754
- /*
755
- Horizontal position of touch
756
- @return {Number}
757
- */
758
-
759
- Imba.Touch.prototype.x = function (){
760
- return this._x;
761
- };
762
-
763
- /*
764
- Vertical position of touch
765
- @return {Number}
766
- */
767
-
768
- Imba.Touch.prototype.y = function (){
769
- return this._y;
770
- };
771
-
772
- /*
773
- Horizontal position of touch relative to target
774
- @return {Number}
775
- */
776
-
777
- Imba.Touch.prototype.tx = function (){
778
- this._targetBox || (this._targetBox = this._target.dom().getBoundingClientRect());
779
- return this._x - this._targetBox.left;
780
- };
781
-
782
- /*
783
- Vertical position of touch relative to target
784
- @return {Number}
785
- */
786
-
787
- Imba.Touch.prototype.ty = function (){
788
- this._targetBox || (this._targetBox = this._target.dom().getBoundingClientRect());
789
- return this._y - this._targetBox.top;
790
- };
791
-
792
- /*
793
- Button pressed in this touch. Native touches defaults to left-click (0)
794
- @return {Number}
795
- */
796
-
797
- Imba.Touch.prototype.button = function (){
798
- return this._button;
799
- }; // @pointer ? @pointer.button : 0
800
-
801
- Imba.Touch.prototype.sourceTarget = function (){
802
- return this._sourceTarget;
803
- };
804
-
805
-
806
- Imba.TouchGesture = function TouchGesture(){ };
807
-
808
-
809
- Imba.TouchGesture.prototype.__active = {'default': false,name: 'active'};
810
- Imba.TouchGesture.prototype.active = function(v){ return this._active; }
811
- Imba.TouchGesture.prototype.setActive = function(v){ this._active = v; return this; }
812
- Imba.TouchGesture.prototype._active = false;
813
-
814
- Imba.TouchGesture.prototype.ontouchstart = function (e){
815
- return this;
816
- };
817
-
818
- Imba.TouchGesture.prototype.ontouchupdate = function (e){
819
- return this;
820
- };
821
-
822
- Imba.TouchGesture.prototype.ontouchend = function (e){
823
- return this;
824
- };
825
-
826
-
827
- // A Touch-event is created on mousedown (always)
828
- // and while it exists, mousemove and mouseup will
829
- // be delegated to this active event.
830
- Imba.POINTER = new Imba.Pointer();
831
- Imba.POINTERS = [Imba.POINTER];
832
-
833
-
834
- // regular event stuff
835
- Imba.KEYMAP = {
836
- "8": 'backspace',
837
- "9": 'tab',
838
- "13": 'enter',
839
- "16": 'shift',
840
- "17": 'ctrl',
841
- "18": 'alt',
842
- "19": 'break',
843
- "20": 'caps',
844
- "27": 'esc',
845
- "32": 'space',
846
- "35": 'end',
847
- "36": 'home',
848
- "37": 'larr',
849
- "38": 'uarr',
850
- "39": 'rarr',
851
- "40": 'darr',
852
- "45": 'insert',
853
- "46": 'delete',
854
- "107": 'plus',
855
- "106": 'mult',
856
- "91": 'meta'
857
- };
858
-
859
- Imba.CHARMAP = {
860
- "%": 'modulo',
861
- "*": 'multiply',
862
- "+": 'add',
863
- "-": 'sub',
864
- "/": 'divide',
865
- ".": 'dot'
866
- };
867
-
868
- /*
869
- Imba handles all events in the dom through a single manager,
870
- listening at the root of your document. If Imba finds a tag
871
- that listens to a certain event, the event will be wrapped
872
- in an `Imba.Event`, which normalizes some of the quirks and
873
- browser differences.
874
-
875
- @iname event
876
- */
877
-
878
- Imba.Event = function Event(e){
879
- this.setEvent(e);
880
- this.setBubble(true);
881
- };
882
-
883
- /* reference to the native event */
884
-
885
-
886
-
887
- Imba.Event.prototype.event = function(v){ return this._event; }
888
- Imba.Event.prototype.setEvent = function(v){ this._event = v; return this; };
889
-
890
- /* reference to the native event */
891
-
892
-
893
-
894
- Imba.Event.prototype.prefix = function(v){ return this._prefix; }
895
- Imba.Event.prototype.setPrefix = function(v){ this._prefix = v; return this; };
896
-
897
-
898
-
899
- Imba.Event.prototype.data = function(v){ return this._data; }
900
- Imba.Event.prototype.setData = function(v){ this._data = v; return this; };
901
-
902
- /*
903
- should remove this alltogether?
904
- @deprecated
905
- */
906
-
907
-
908
-
909
- Imba.Event.prototype.source = function(v){ return this._source; }
910
- Imba.Event.prototype.setSource = function(v){ this._source = v; return this; };
911
-
912
- /* A {Boolean} indicating whether the event bubbles up or not */
913
-
914
-
915
- Imba.Event.prototype.__bubble = {type: Boolean,chainable: true,name: 'bubble'};
916
- Imba.Event.prototype.bubble = function(v){ return v !== undefined ? (this.setBubble(v),this) : this._bubble; }
917
- Imba.Event.prototype.setBubble = function(v){ this._bubble = v; return this; };
918
-
919
- Imba.Event.wrap = function (e){
920
- return new this(e);
921
- };
922
-
923
- Imba.Event.prototype.setType = function (type){
924
- this._type = type;
925
- return this;
926
- };
927
-
928
- /*
929
- @return {String} The name of the event (case-insensitive)
930
- */
931
-
932
- Imba.Event.prototype.type = function (){
933
- return this._type || this.event().type;
934
- };
935
-
936
- Imba.Event.prototype.name = function (){
937
- return this._name || (this._name = this.type().toLowerCase().replace(/\:/g,''));
938
- };
939
-
940
- // mimc getset
941
- Imba.Event.prototype.bubble = function (v){
942
- if (v != undefined) {
943
- this.setBubble(v);
944
- return this;
945
- };
946
- return this._bubble;
947
- };
948
-
949
- /*
950
- Prevents further propagation of the current event.
951
- @return {self}
952
- */
953
-
954
- Imba.Event.prototype.halt = function (){
955
- this.setBubble(false);
956
- return this;
957
- };
958
-
959
- /*
960
- Cancel the event (if cancelable). In the case of native events it
961
- will call `preventDefault` on the wrapped event object.
962
- @return {self}
963
- */
964
-
965
- Imba.Event.prototype.cancel = function (){
966
- if (this.event().preventDefault) { this.event().preventDefault() };
967
- this._cancel = true;
968
- return this;
969
- };
970
-
971
- /*
972
- Indicates whether or not event.cancel has been called.
973
-
974
- @return {Boolean}
975
- */
976
-
977
- Imba.Event.prototype.isPrevented = function (){
978
- return this.event() && this.event().defaultPrevented || this._cancel;
979
- };
980
-
981
- /*
982
- A reference to the initial target of the event.
983
- */
984
-
985
- Imba.Event.prototype.target = function (){
986
- return tag$wrap(this.event()._target || this.event().target);
987
- };
988
-
989
- /*
990
- A reference to the object responding to the event.
991
- */
992
-
993
- Imba.Event.prototype.responder = function (){
994
- return this._responder;
995
- };
996
-
997
- /*
998
- Redirect the event to new target
999
- */
1000
-
1001
- Imba.Event.prototype.redirect = function (node){
1002
- this._redirect = node;
1003
- return this;
1004
- };
1005
-
1006
- /*
1007
- Get the normalized character for KeyboardEvent/TextEvent
1008
- @return {String}
1009
- */
1010
-
1011
- Imba.Event.prototype.keychar = function (){
1012
- if (this.event() instanceof TextEvent) {
1013
- return this.event().data;
1014
- };
1015
-
1016
- if (this.event() instanceof KeyboardEvent) {
1017
- var ki = this.event().keyIdentifier;
1018
- var sym = Imba.KEYMAP[this.event().keyCode];
1019
-
1020
- // p 'keysym!',ki,sym
1021
-
1022
- if (!sym && ki.substr(0,2) == "U+") {
1023
- sym = String.fromCharCode(parseInt(ki.substr(2),16));
1024
- };
1025
- return sym;
1026
- };
1027
-
1028
- return null;
1029
- };
1030
-
1031
- /*
1032
- @deprecated
1033
- */
1034
-
1035
- Imba.Event.prototype.keycombo = function (){
1036
- var sym;
1037
- if (!(sym = this.keychar())) { return };
1038
- sym = Imba.CHARMAP[sym] || sym;
1039
- var combo = [],e = this.event();
1040
- if (e.ctrlKey) { combo.push('ctrl') };
1041
- if (e.shiftKey) { combo.push('shift') };
1042
- if (e.altKey) { combo.push('alt') };
1043
- if (e.metaKey) { combo.push('cmd') };
1044
- combo.push(sym);
1045
- return combo.join("_").toLowerCase();
1046
- };
1047
-
1048
-
1049
- Imba.Event.prototype.process = function (){
1050
- var node;
1051
- var meth = ("on" + (this._prefix || '') + this.name());
1052
- var args = null;
1053
- var domtarget = this.event()._target || this.event().target;
1054
- // var node = <{domtarget:_responder or domtarget}>
1055
- // need to clean up and document this behaviour
1056
-
1057
- var domnode = domtarget._responder || domtarget;
1058
- // @todo need to stop infinite redirect-rules here
1059
-
1060
- var $1;while (domnode){
1061
- this._redirect = null;
1062
- if (node = tag$wrap(domnode)) { // not only tag
1063
-
1064
- if ((typeof node[($1 = meth)]=='string'||node[$1] instanceof String)) {
1065
- // should remember the receiver of the event
1066
- meth = node[meth];
1067
- continue; // should not continue?
1068
- };
1069
-
1070
- if (node[meth] instanceof Array) {
1071
- args = node[meth].concat(node);
1072
- meth = args.shift();
1073
- continue; // should not continue?
1074
- };
1075
-
1076
- if (node[meth] instanceof Function) {
1077
- this._responder || (this._responder = node);
1078
- // should autostop bubble here?
1079
- args ? (node[meth].apply(node,args)) : (node[meth](this,this.data()));
1080
- };
1081
- };
1082
-
1083
- // add node.nextEventResponder as a separate method here?
1084
- if (!(this.bubble() && (domnode = (this._redirect || (node ? (node.parent()) : (domnode.parentNode)))))) {
1085
- break;
1086
- };
1087
- };
1088
-
1089
- this.processed();
1090
- return this;
1091
- };
1092
-
1093
-
1094
- Imba.Event.prototype.processed = function (){
1095
- Imba.emit(Imba,'event',[this]);
1096
- return this;
1097
- };
1098
-
1099
- /*
1100
- Return the x/left coordinate of the mouse / pointer for this event
1101
- @return {Number} x coordinate of mouse / pointer for event
1102
- */
1103
-
1104
- Imba.Event.prototype.x = function (){
1105
- return this.event().x;
1106
- };
1107
-
1108
- /*
1109
- Return the y/top coordinate of the mouse / pointer for this event
1110
- @return {Number} y coordinate of mouse / pointer for event
1111
- */
1112
-
1113
- Imba.Event.prototype.y = function (){
1114
- return this.event().y;
1115
- };
1116
-
1117
- /*
1118
- Returns a Number representing a system and implementation
1119
- dependent numeric code identifying the unmodified value of the
1120
- pressed key; this is usually the same as keyCode.
1121
-
1122
- For mouse-events, the returned value indicates which button was
1123
- pressed on the mouse to trigger the event.
1124
-
1125
- @return {Number}
1126
- */
1127
-
1128
- Imba.Event.prototype.which = function (){
1129
- return this.event().which;
1130
- };
1131
-
1132
-
1133
- /*
1134
-
1135
- Manager for listening to and delegating events in Imba. A single instance
1136
- is always created by Imba (as `Imba.Events`), which handles and delegates all
1137
- events at the very root of the document. Imba does not capture all events
1138
- by default, so if you want to make sure exotic or custom DOMEvents are delegated
1139
- in Imba you will need to register them in `Imba.Events.register(myCustomEventName)`
1140
-
1141
- @iname manager
1142
-
1143
- */
1144
-
1145
- Imba.EventManager = function EventManager(node,pars){
1146
- var self = this;
1147
- if(!pars||pars.constructor !== Object) pars = {};
1148
- var events = pars.events !== undefined ? pars.events : [];
1149
- self.setRoot(node);
1150
- self.setCount(0);
1151
- self.setListeners([]);
1152
- self.setDelegators({});
1153
- self.setDelegator(function(e) {
1154
- // console.log "delegating event?! {e}"
1155
- self.delegate(e);
1156
- return true;
1157
- });
1158
-
1159
- for (var i = 0, ary = iter$(events), len = ary.length; i < len; i++) {
1160
- self.register(ary[i]);
1161
- };
1162
-
1163
- return self;
1164
- };
1165
-
1166
-
1167
-
1168
- Imba.EventManager.prototype.root = function(v){ return this._root; }
1169
- Imba.EventManager.prototype.setRoot = function(v){ this._root = v; return this; };
1170
-
1171
-
1172
- Imba.EventManager.prototype.count = function(v){ return this._count; }
1173
- Imba.EventManager.prototype.setCount = function(v){ this._count = v; return this; };
1174
-
1175
- Imba.EventManager.prototype.__enabled = {'default': false,watch: 'enabledDidSet',name: 'enabled'};
1176
- Imba.EventManager.prototype.enabled = function(v){ return this._enabled; }
1177
- Imba.EventManager.prototype.setEnabled = function(v){
1178
- var a = this.enabled();
1179
- if(v != a) { this._enabled = v; }
1180
- if(v != a) { this.enabledDidSet && this.enabledDidSet(v,a,this.__enabled) }
1181
- return this;
1182
- }
1183
- Imba.EventManager.prototype._enabled = false;
1184
-
1185
-
1186
- Imba.EventManager.prototype.listeners = function(v){ return this._listeners; }
1187
- Imba.EventManager.prototype.setListeners = function(v){ this._listeners = v; return this; };
1188
-
1189
-
1190
- Imba.EventManager.prototype.delegators = function(v){ return this._delegators; }
1191
- Imba.EventManager.prototype.setDelegators = function(v){ this._delegators = v; return this; };
1192
-
1193
-
1194
- Imba.EventManager.prototype.delegator = function(v){ return this._delegator; }
1195
- Imba.EventManager.prototype.setDelegator = function(v){ this._delegator = v; return this; };
1196
-
1197
- Imba.EventManager.prototype.enabledDidSet = function (bool){
1198
- bool ? (this.onenable()) : (this.ondisable());
1199
- return this;
1200
- };
1201
-
1202
- /*
1203
-
1204
- Tell the current EventManager to intercept and handle event of a certain name.
1205
- By default, Imba.Events will register interceptors for: *keydown*, *keyup*,
1206
- *keypress*, *textInput*, *input*, *change*, *submit*, *focusin*, *focusout*,
1207
- *blur*, *contextmenu*, *dblclick*, *mousewheel*, *wheel*
1208
-
1209
- */
1210
-
1211
- Imba.EventManager.prototype.register = function (name,handler){
1212
- if(handler === undefined) handler = true;
1213
- if (name instanceof Array) {
1214
- for (var i = 0, ary = iter$(name), len = ary.length; i < len; i++) {
1215
- this.register(ary[i],handler);
1216
- };
1217
- return this;
1218
- };
1219
-
1220
- if (this.delegators()[name]) { return this };
1221
- // console.log("register for event {name}")
1222
- var fn = this.delegators()[name] = handler instanceof Function ? (handler) : (this.delegator());
1223
- if (this.enabled()) { return this.root().addEventListener(name,fn,true) };
1224
- };
1225
-
1226
- Imba.EventManager.prototype.listen = function (name,handler,capture){
1227
- if(capture === undefined) capture = true;
1228
- this.listeners().push([name,handler,capture]);
1229
- if (this.enabled()) { this.root().addEventListener(name,handler,capture) };
1230
- return this;
1231
- };
1232
-
1233
- Imba.EventManager.prototype.delegate = function (e){
1234
- this.setCount(this.count() + 1);
1235
- var event = Imba.Event.wrap(e);
1236
- event.process();
1237
- return this;
1238
- };
1239
-
1240
- Imba.EventManager.prototype.create = function (type,target,pars){
1241
- if(!pars||pars.constructor !== Object) pars = {};
1242
- var data = pars.data !== undefined ? pars.data : null;
1243
- var source = pars.source !== undefined ? pars.source : null;
1244
- var event = Imba.Event.wrap({type: type,target: target});
1245
- if (data) { (event.setData(data),data) };
1246
- if (source) { (event.setSource(source),source) };
1247
- return event;
1248
- };
1249
-
1250
- // use create instead?
1251
- Imba.EventManager.prototype.trigger = function (){
1252
- return this.create.apply(this,arguments).process();
1253
- };
1254
-
1255
- Imba.EventManager.prototype.onenable = function (){
1256
- for (var o = this.delegators(), i = 0, keys = Object.keys(o), l = keys.length; i < l; i++){
1257
- this.root().addEventListener(keys[i],o[keys[i]],true);
1258
- };
1259
-
1260
- for (var j = 0, ary = iter$(this.listeners()), len = ary.length, item; j < len; j++) {
1261
- item = ary[j];
1262
- this.root().addEventListener(item[0],item[1],item[2]);
1263
- };
1264
- return this;
1265
- };
1266
-
1267
- Imba.EventManager.prototype.ondisable = function (){
1268
- for (var o = this.delegators(), i = 0, keys = Object.keys(o), l = keys.length; i < l; i++){
1269
- this.root().removeEventListener(keys[i],o[keys[i]],true);
1270
- };
1271
-
1272
- for (var j = 0, ary = iter$(this.listeners()), len = ary.length, item; j < len; j++) {
1273
- item = ary[j];
1274
- this.root().removeEventListener(item[0],item[1],item[2]);
1275
- };
1276
- return this;
1277
- };
1278
-
1279
-
1280
- ED = Imba.Events = new Imba.EventManager(document,{events: [
1281
- 'keydown','keyup','keypress','textInput','input','change','submit',
1282
- 'focusin','focusout','blur','contextmenu','dblclick',
1283
- 'mousewheel','wheel'
1284
- ]});
1285
-
1286
- // should set these up inside the Imba.Events object itself
1287
- // so that we can have different EventManager for different roots
1288
-
1289
- if (hasTouchEvents) {
1290
- Imba.Events.listen('touchstart',function(e) {
1291
- var Events_, v_;
1292
- (((Events_ = Imba.Events).setCount(v_ = Events_.count() + 1),v_)) - 1;
1293
- return Imba.Touch.ontouchstart(e);
1294
- });
1295
-
1296
- Imba.Events.listen('touchmove',function(e) {
1297
- var Events_, v_;
1298
- (((Events_ = Imba.Events).setCount(v_ = Events_.count() + 1),v_)) - 1;
1299
- return Imba.Touch.ontouchmove(e);
1300
- });
1301
-
1302
- Imba.Events.listen('touchend',function(e) {
1303
- var Events_, v_;
1304
- (((Events_ = Imba.Events).setCount(v_ = Events_.count() + 1),v_)) - 1;
1305
- return Imba.Touch.ontouchend(e);
1306
- });
1307
-
1308
- Imba.Events.listen('touchcancel',function(e) {
1309
- var Events_, v_;
1310
- (((Events_ = Imba.Events).setCount(v_ = Events_.count() + 1),v_)) - 1;
1311
- return Imba.Touch.ontouchcancel(e);
1312
- });
1313
- };
1314
-
1315
- Imba.Events.register('click',function(e) {
1316
- // Only for main mousebutton, no?
1317
- if ((e.timeStamp - lastNativeTouchTimeStamp) > lastNativeTouchTimeout) {
1318
- var tap = new Imba.Event(e);
1319
- tap.setType('tap');
1320
- tap.process();
1321
- if (tap._responder) {
1322
- return e.preventDefault();
1323
- };
1324
- };
1325
- // delegate the real click event
1326
- return Imba.Events.delegate(e);
1327
- });
1328
-
1329
- Imba.Events.listen('mousedown',function(e) {
1330
- if ((e.timeStamp - lastNativeTouchTimeStamp) > lastNativeTouchTimeout) {
1331
- if (Imba.POINTER) { return Imba.POINTER.update(e).process() };
1332
- };
1333
- });
1334
-
1335
- // Imba.Events.listen(:mousemove) do |e|
1336
- // # console.log 'mousemove',e:timeStamp
1337
- // if (e:timeStamp - lastNativeTouchTimeStamp) > lastNativeTouchTimeout
1338
- // Imba.POINTER.update(e).process if Imba.POINTER # .process if touch # should not happen? We process through
1339
-
1340
- Imba.Events.listen('mouseup',function(e) {
1341
- // console.log 'mouseup',e:timeStamp
1342
- if ((e.timeStamp - lastNativeTouchTimeStamp) > lastNativeTouchTimeout) {
1343
- if (Imba.POINTER) { return Imba.POINTER.update(e).process() };
1344
- };
1345
- });
1346
-
1347
-
1348
- Imba.Events.register(['mousedown','mouseup']);
1349
- return (Imba.Events.setEnabled(true),true);
1350
-
1351
- })()
1352
- },{}],5:[function(require,module,exports){
1353
- (function(){
1354
-
1355
- // predefine all supported html tags
1356
- tag$.defineTag('fragment', 'htmlelement', function(tag){
1357
-
1358
- tag.createNode = function (){
1359
- return Imba.document().createDocumentFragment();
1360
- };
1361
- });
1362
-
1363
- tag$.defineTag('a', function(tag){
1364
-
1365
-
1366
- tag.prototype.href = function(v){ return this.getAttribute('href'); }
1367
- tag.prototype.setHref = function(v){ this.setAttribute('href',v); return this; };
1368
- });
1369
-
1370
- tag$.defineTag('abbr');
1371
- tag$.defineTag('address');
1372
- tag$.defineTag('area');
1373
- tag$.defineTag('article');
1374
- tag$.defineTag('aside');
1375
- tag$.defineTag('audio');
1376
- tag$.defineTag('b');
1377
- tag$.defineTag('base');
1378
- tag$.defineTag('bdi');
1379
- tag$.defineTag('bdo');
1380
- tag$.defineTag('big');
1381
- tag$.defineTag('blockquote');
1382
- tag$.defineTag('body');
1383
- tag$.defineTag('br');
1384
-
1385
- tag$.defineTag('button', function(tag){
1386
-
1387
-
1388
- tag.prototype.autofocus = function(v){ return this.getAttribute('autofocus'); }
1389
- tag.prototype.setAutofocus = function(v){ this.setAttribute('autofocus',v); return this; };
1390
-
1391
-
1392
- tag.prototype.type = function(v){ return this.getAttribute('type'); }
1393
- tag.prototype.setType = function(v){ this.setAttribute('type',v); return this; };
1394
-
1395
-
1396
- tag.prototype.disabled = function(v){ return this.getAttribute('disabled'); }
1397
- tag.prototype.setDisabled = function(v){ this.setAttribute('disabled',v); return this; };
1398
- });
1399
-
1400
- tag$.defineTag('canvas', function(tag){
1401
- tag.prototype.setWidth = function (val){
1402
- if (this.width() != val) { this.dom().width = val };
1403
- return this;
1404
- };
1405
-
1406
- tag.prototype.setHeight = function (val){
1407
- if (this.height() != val) { this.dom().height = val };
1408
- return this;
1409
- };
1410
-
1411
- tag.prototype.width = function (){
1412
- return this.dom().width;
1413
- };
1414
-
1415
- tag.prototype.height = function (){
1416
- return this.dom().height;
1417
- };
1418
-
1419
- tag.prototype.context = function (type){
1420
- if(type === undefined) type = '2d';
1421
- return this.dom().getContext(type);
1422
- };
1423
- });
1424
-
1425
- tag$.defineTag('caption');
1426
- tag$.defineTag('cite');
1427
- tag$.defineTag('code');
1428
- tag$.defineTag('col');
1429
- tag$.defineTag('colgroup');
1430
- tag$.defineTag('data');
1431
- tag$.defineTag('datalist');
1432
- tag$.defineTag('dd');
1433
- tag$.defineTag('del');
1434
- tag$.defineTag('details');
1435
- tag$.defineTag('dfn');
1436
- tag$.defineTag('div');
1437
- tag$.defineTag('dl');
1438
- tag$.defineTag('dt');
1439
- tag$.defineTag('em');
1440
- tag$.defineTag('embed');
1441
- tag$.defineTag('fieldset');
1442
- tag$.defineTag('figcaption');
1443
- tag$.defineTag('figure');
1444
- tag$.defineTag('footer');
1445
-
1446
- tag$.defineTag('form', function(tag){
1447
-
1448
-
1449
- tag.prototype.method = function(v){ return this.getAttribute('method'); }
1450
- tag.prototype.setMethod = function(v){ this.setAttribute('method',v); return this; };
1451
-
1452
-
1453
- tag.prototype.action = function(v){ return this.getAttribute('action'); }
1454
- tag.prototype.setAction = function(v){ this.setAttribute('action',v); return this; };
1455
- });
1456
-
1457
- tag$.defineTag('h1');
1458
- tag$.defineTag('h2');
1459
- tag$.defineTag('h3');
1460
- tag$.defineTag('h4');
1461
- tag$.defineTag('h5');
1462
- tag$.defineTag('h6');
1463
- tag$.defineTag('head');
1464
- tag$.defineTag('header');
1465
- tag$.defineTag('hr');
1466
- tag$.defineTag('html');
1467
- tag$.defineTag('i');
1468
-
1469
- tag$.defineTag('iframe', function(tag){
1470
-
1471
-
1472
- tag.prototype.src = function(v){ return this.getAttribute('src'); }
1473
- tag.prototype.setSrc = function(v){ this.setAttribute('src',v); return this; };
1474
- });
1475
-
1476
- tag$.defineTag('img', function(tag){
1477
-
1478
-
1479
- tag.prototype.src = function(v){ return this.getAttribute('src'); }
1480
- tag.prototype.setSrc = function(v){ this.setAttribute('src',v); return this; };
1481
- });
1482
-
1483
- tag$.defineTag('input', function(tag){
1484
- // can use attr instead
1485
-
1486
-
1487
- tag.prototype.name = function(v){ return this.getAttribute('name'); }
1488
- tag.prototype.setName = function(v){ this.setAttribute('name',v); return this; };
1489
-
1490
-
1491
- tag.prototype.type = function(v){ return this.getAttribute('type'); }
1492
- tag.prototype.setType = function(v){ this.setAttribute('type',v); return this; };
1493
-
1494
-
1495
- tag.prototype.required = function(v){ return this.getAttribute('required'); }
1496
- tag.prototype.setRequired = function(v){ this.setAttribute('required',v); return this; };
1497
-
1498
-
1499
- tag.prototype.disabled = function(v){ return this.getAttribute('disabled'); }
1500
- tag.prototype.setDisabled = function(v){ this.setAttribute('disabled',v); return this; };
1501
-
1502
-
1503
- tag.prototype.autofocus = function(v){ return this.getAttribute('autofocus'); }
1504
- tag.prototype.setAutofocus = function(v){ this.setAttribute('autofocus',v); return this; };
1505
-
1506
- tag.prototype.value = function (){
1507
- return this.dom().value;
1508
- };
1509
-
1510
- tag.prototype.setValue = function (v){
1511
- if (v != this.dom().value) { this.dom().value = v };
1512
- return this;
1513
- };
1514
-
1515
- tag.prototype.setPlaceholder = function (v){
1516
- if (v != this.dom().placeholder) { this.dom().placeholder = v };
1517
- return this;
1518
- };
1519
-
1520
- tag.prototype.placeholder = function (){
1521
- return this.dom().placeholder;
1522
- };
1523
-
1524
- tag.prototype.checked = function (){
1525
- return this.dom().checked;
1526
- };
1527
-
1528
- tag.prototype.setChecked = function (bool){
1529
- if (bool != this.dom().checked) { this.dom().checked = bool };
1530
- return this;
1531
- };
1532
- });
1533
-
1534
- tag$.defineTag('ins');
1535
- tag$.defineTag('kbd');
1536
- tag$.defineTag('keygen');
1537
- tag$.defineTag('label');
1538
- tag$.defineTag('legend');
1539
- tag$.defineTag('li');
1540
-
1541
- tag$.defineTag('link', function(tag){
1542
-
1543
-
1544
- tag.prototype.rel = function(v){ return this.getAttribute('rel'); }
1545
- tag.prototype.setRel = function(v){ this.setAttribute('rel',v); return this; };
1546
-
1547
-
1548
- tag.prototype.type = function(v){ return this.getAttribute('type'); }
1549
- tag.prototype.setType = function(v){ this.setAttribute('type',v); return this; };
1550
-
1551
-
1552
- tag.prototype.href = function(v){ return this.getAttribute('href'); }
1553
- tag.prototype.setHref = function(v){ this.setAttribute('href',v); return this; };
1554
-
1555
-
1556
- tag.prototype.media = function(v){ return this.getAttribute('media'); }
1557
- tag.prototype.setMedia = function(v){ this.setAttribute('media',v); return this; };
1558
- });
1559
-
1560
- tag$.defineTag('main');
1561
- tag$.defineTag('map');
1562
- tag$.defineTag('mark');
1563
- tag$.defineTag('menu');
1564
- tag$.defineTag('menuitem');
1565
-
1566
- tag$.defineTag('meta', function(tag){
1567
-
1568
-
1569
- tag.prototype.name = function(v){ return this.getAttribute('name'); }
1570
- tag.prototype.setName = function(v){ this.setAttribute('name',v); return this; };
1571
-
1572
-
1573
- tag.prototype.content = function(v){ return this.getAttribute('content'); }
1574
- tag.prototype.setContent = function(v){ this.setAttribute('content',v); return this; };
1575
-
1576
-
1577
- tag.prototype.charset = function(v){ return this.getAttribute('charset'); }
1578
- tag.prototype.setCharset = function(v){ this.setAttribute('charset',v); return this; };
1579
- });
1580
-
1581
- tag$.defineTag('meter');
1582
- tag$.defineTag('nav');
1583
- tag$.defineTag('noscript');
1584
- tag$.defineTag('object');
1585
- tag$.defineTag('ol');
1586
- tag$.defineTag('optgroup');
1587
-
1588
- tag$.defineTag('option', function(tag){
1589
-
1590
-
1591
- tag.prototype.value = function(v){ return this.getAttribute('value'); }
1592
- tag.prototype.setValue = function(v){ this.setAttribute('value',v); return this; };
1593
- });
1594
-
1595
- tag$.defineTag('output');
1596
- tag$.defineTag('p');
1597
- tag$.defineTag('param');
1598
- tag$.defineTag('pre');
1599
- tag$.defineTag('progress');
1600
- tag$.defineTag('q');
1601
- tag$.defineTag('rp');
1602
- tag$.defineTag('rt');
1603
- tag$.defineTag('ruby');
1604
- tag$.defineTag('s');
1605
- tag$.defineTag('samp');
1606
-
1607
- tag$.defineTag('script', function(tag){
1608
-
1609
-
1610
- tag.prototype.src = function(v){ return this.getAttribute('src'); }
1611
- tag.prototype.setSrc = function(v){ this.setAttribute('src',v); return this; };
1612
-
1613
-
1614
- tag.prototype.type = function(v){ return this.getAttribute('type'); }
1615
- tag.prototype.setType = function(v){ this.setAttribute('type',v); return this; };
1616
- });
1617
-
1618
- tag$.defineTag('section');
1619
-
1620
- tag$.defineTag('select', function(tag){
1621
-
1622
-
1623
- tag.prototype.name = function(v){ return this.getAttribute('name'); }
1624
- tag.prototype.setName = function(v){ this.setAttribute('name',v); return this; };
1625
-
1626
-
1627
- tag.prototype.multiple = function(v){ return this.getAttribute('multiple'); }
1628
- tag.prototype.setMultiple = function(v){ this.setAttribute('multiple',v); return this; };
1629
-
1630
-
1631
- tag.prototype.required = function(v){ return this.getAttribute('required'); }
1632
- tag.prototype.setRequired = function(v){ this.setAttribute('required',v); return this; };
1633
-
1634
-
1635
- tag.prototype.disabled = function(v){ return this.getAttribute('disabled'); }
1636
- tag.prototype.setDisabled = function(v){ this.setAttribute('disabled',v); return this; };
1637
-
1638
- tag.prototype.value = function (){
1639
- return this.dom().value;
1640
- };
1641
-
1642
- tag.prototype.setValue = function (v){
1643
- if (v != this.dom().value) { this.dom().value = v };
1644
- return this;
1645
- };
1646
- });
1647
-
1648
-
1649
- tag$.defineTag('small');
1650
- tag$.defineTag('source');
1651
- tag$.defineTag('span');
1652
- tag$.defineTag('strong');
1653
- tag$.defineTag('style');
1654
- tag$.defineTag('sub');
1655
- tag$.defineTag('summary');
1656
- tag$.defineTag('sup');
1657
- tag$.defineTag('table');
1658
- tag$.defineTag('tbody');
1659
- tag$.defineTag('td');
1660
-
1661
- tag$.defineTag('textarea', function(tag){
1662
-
1663
-
1664
- tag.prototype.name = function(v){ return this.getAttribute('name'); }
1665
- tag.prototype.setName = function(v){ this.setAttribute('name',v); return this; };
1666
-
1667
-
1668
- tag.prototype.disabled = function(v){ return this.getAttribute('disabled'); }
1669
- tag.prototype.setDisabled = function(v){ this.setAttribute('disabled',v); return this; };
1670
-
1671
-
1672
- tag.prototype.required = function(v){ return this.getAttribute('required'); }
1673
- tag.prototype.setRequired = function(v){ this.setAttribute('required',v); return this; };
1674
-
1675
-
1676
- tag.prototype.rows = function(v){ return this.getAttribute('rows'); }
1677
- tag.prototype.setRows = function(v){ this.setAttribute('rows',v); return this; };
1678
-
1679
-
1680
- tag.prototype.cols = function(v){ return this.getAttribute('cols'); }
1681
- tag.prototype.setCols = function(v){ this.setAttribute('cols',v); return this; };
1682
-
1683
-
1684
- tag.prototype.autofocus = function(v){ return this.getAttribute('autofocus'); }
1685
- tag.prototype.setAutofocus = function(v){ this.setAttribute('autofocus',v); return this; };
1686
-
1687
- tag.prototype.value = function (){
1688
- return this.dom().value;
1689
- };
1690
-
1691
- tag.prototype.setValue = function (v){
1692
- if (v != this.dom().value) { this.dom().value = v };
1693
- return this;
1694
- };
1695
-
1696
- tag.prototype.setPlaceholder = function (v){
1697
- if (v != this.dom().placeholder) { this.dom().placeholder = v };
1698
- return this;
1699
- };
1700
-
1701
- tag.prototype.placeholder = function (){
1702
- return this.dom().placeholder;
1703
- };
1704
- });
1705
-
1706
- tag$.defineTag('tfoot');
1707
- tag$.defineTag('th');
1708
- tag$.defineTag('thead');
1709
- tag$.defineTag('time');
1710
- tag$.defineTag('title');
1711
- tag$.defineTag('tr');
1712
- tag$.defineTag('track');
1713
- tag$.defineTag('u');
1714
- tag$.defineTag('ul');
1715
- tag$.defineTag('video');
1716
- return tag$.defineTag('wbr');
1717
-
1718
- })()
1719
- },{}],6:[function(require,module,exports){
1720
- (function(){
1721
- function iter$(a){ return a ? (a.toArray ? a.toArray() : a) : []; };
1722
-
1723
- Imba.document = function (){
1724
- return window.document;
1725
- };
1726
-
1727
- /*
1728
- Returns the body element wrapped in an Imba.Tag
1729
- */
1730
-
1731
- Imba.root = function (){
1732
- return tag$wrap(Imba.document().body);
1733
- };
1734
-
1735
- tag$.defineTag('htmlelement', 'element', function(tag){
1736
-
1737
- /*
1738
- Called when a tag type is being subclassed.
1739
- */
1740
-
1741
- tag.inherit = function (child){
1742
- child.prototype._empty = true;
1743
- child._protoDom = null;
1744
-
1745
- if (this._nodeType) {
1746
- child._nodeType = this._nodeType;
1747
-
1748
- var className = "_" + child._name.replace(/_/g,'-');
1749
- if (child._name[0] != '#') { return child._classes = this._classes.concat(className) };
1750
- } else {
1751
- child._nodeType = child._name;
1752
- return child._classes = [];
1753
- };
1754
- };
1755
-
1756
- tag.buildNode = function (){
1757
- var dom = Imba.document().createElement(this._nodeType);
1758
- var cls = this._classes.join(" ");
1759
- if (cls) { dom.className = cls };
1760
- return dom;
1761
- };
1762
-
1763
- tag.createNode = function (){
1764
- var proto = (this._protoDom || (this._protoDom = this.buildNode()));
1765
- return proto.cloneNode(false);
1766
- };
1767
-
1768
- tag.dom = function (){
1769
- return this._protoDom || (this._protoDom = this.buildNode());
1770
- };
1771
-
1772
-
1773
-
1774
- tag.prototype.id = function(v){ return this.getAttribute('id'); }
1775
- tag.prototype.setId = function(v){ this.setAttribute('id',v); return this; };
1776
-
1777
-
1778
- tag.prototype.tabindex = function(v){ return this.getAttribute('tabindex'); }
1779
- tag.prototype.setTabindex = function(v){ this.setAttribute('tabindex',v); return this; };
1780
-
1781
-
1782
- tag.prototype.title = function(v){ return this.getAttribute('title'); }
1783
- tag.prototype.setTitle = function(v){ this.setAttribute('title',v); return this; };
1784
-
1785
-
1786
- tag.prototype.role = function(v){ return this.getAttribute('role'); }
1787
- tag.prototype.setRole = function(v){ this.setAttribute('role',v); return this; };
1788
-
1789
- tag.prototype.width = function (){
1790
- return this._dom.offsetWidth;
1791
- };
1792
-
1793
- tag.prototype.height = function (){
1794
- return this._dom.offsetHeight;
1795
- };
1796
-
1797
- tag.prototype.setChildren = function (nodes,type){
1798
- this._empty ? (this.append(nodes)) : (this.empty().append(nodes));
1799
- this._children = null;
1800
- return this;
1801
- };
1802
-
1803
- /*
1804
- Set inner html of node
1805
- */
1806
-
1807
- tag.prototype.setHtml = function (html){
1808
- this._dom.innerHTML = html;
1809
- return this;
1810
- };
1811
-
1812
- /*
1813
- Get inner html of node
1814
- */
1815
-
1816
- tag.prototype.html = function (){
1817
- return this._dom.innerHTML;
1818
- };
1819
-
1820
- /*
1821
- Remove all content inside node
1822
- */
1823
-
1824
- tag.prototype.empty = function (){
1825
- while (this._dom.firstChild){
1826
- this._dom.removeChild(this._dom.firstChild);
1827
- };
1828
- this._children = null;
1829
- this._empty = true;
1830
- return this;
1831
- };
1832
-
1833
- /*
1834
- Remove specified child from current node.
1835
- */
1836
-
1837
- tag.prototype.remove = function (child){
1838
- var par = this.dom();
1839
- var el = child && child.dom();
1840
- if (el && el.parentNode == par) { par.removeChild(el) };
1841
- return this;
1842
- };
1843
-
1844
- tag.prototype.emit = function (name,pars){
1845
- if(!pars||pars.constructor !== Object) pars = {};
1846
- var data = pars.data !== undefined ? pars.data : null;
1847
- var bubble = pars.bubble !== undefined ? pars.bubble : true;
1848
- Imba.Events.trigger(name,this,{data: data,bubble: bubble});
1849
- return this;
1850
- };
1851
-
1852
- tag.prototype.css = function (key,val){
1853
- if (key instanceof Object) {
1854
- for (var i = 0, keys = Object.keys(key), l = keys.length; i < l; i++){
1855
- this.css(keys[i],key[keys[i]]);
1856
- };
1857
- } else if (val == null) {
1858
- this.dom().style.removeProperty(key);
1859
- } else if (val == undefined) {
1860
- return this.dom().style[key];
1861
- } else {
1862
- if ((typeof val=='number'||val instanceof Number) && key.match(/width|height|left|right|top|bottom/)) {
1863
- val = val + "px";
1864
- };
1865
- this.dom().style[key] = val;
1866
- };
1867
- return this;
1868
- };
1869
-
1870
- tag.prototype.dataset = function (key,val){
1871
- if (key instanceof Object) {
1872
- for (var i = 0, keys = Object.keys(key), l = keys.length; i < l; i++){
1873
- this.dataset(keys[i],key[keys[i]]);
1874
- };
1875
- return this;
1876
- };
1877
-
1878
- if (arguments.length == 2) {
1879
- this.setAttribute(("data-" + key),val);
1880
- return this;
1881
- };
1882
-
1883
- if (key) {
1884
- return this.getAttribute(("data-" + key));
1885
- };
1886
-
1887
- var dataset = this.dom().dataset;
1888
-
1889
- if (!dataset) {
1890
- dataset = {};
1891
- for (var i1 = 0, ary = iter$(this.dom().attributes), len = ary.length, atr; i1 < len; i1++) {
1892
- atr = ary[i1];
1893
- if (atr.name.substr(0,5) == 'data-') {
1894
- dataset[Imba.toCamelCase(atr.name.slice(5))] = atr.value;
1895
- };
1896
- };
1897
- };
1898
-
1899
- return dataset;
1900
- };
1901
-
1902
- /*
1903
- Get descendants of current node, optionally matching selector
1904
- @return {Imba.Selector}
1905
- */
1906
-
1907
- tag.prototype.find = function (sel){
1908
- return new Imba.Selector(sel,this);
1909
- };
1910
-
1911
- /*
1912
- Get the first matching child of node
1913
-
1914
- @return {Imba.Tag}
1915
- */
1916
-
1917
- tag.prototype.first = function (sel){
1918
- return sel ? (this.find(sel).first()) : (tag$wrap(this.dom().firstElementChild));
1919
- };
1920
-
1921
- /*
1922
- Get the last matching child of node
1923
-
1924
- node.last # returns the last child of node
1925
- node.last %span # returns the last span inside node
1926
- node.last do |el| el.text == 'Hi' # return last node with text Hi
1927
-
1928
- @return {Imba.Tag}
1929
- */
1930
-
1931
- tag.prototype.last = function (sel){
1932
- return sel ? (this.find(sel).last()) : (tag$wrap(this.dom().lastElementChild));
1933
- };
1934
-
1935
- /*
1936
- Get the child at index
1937
- */
1938
-
1939
- tag.prototype.child = function (i){
1940
- return tag$wrap(this.dom().children[i || 0]);
1941
- };
1942
-
1943
- tag.prototype.children = function (sel){
1944
- var nodes = new Imba.Selector(null,this,this._dom.children);
1945
- return sel ? (nodes.filter(sel)) : (nodes);
1946
- };
1947
-
1948
- tag.prototype.orphanize = function (){
1949
- var par;
1950
- if (par = this.dom().parentNode) { par.removeChild(this._dom) };
1951
- return this;
1952
- };
1953
-
1954
- tag.prototype.matches = function (sel){
1955
- var fn;
1956
- if (sel instanceof Function) {
1957
- return sel(this);
1958
- };
1959
-
1960
- if (sel.query) { sel = sel.query() };
1961
- if (fn = (this._dom.webkitMatchesSelector || this._dom.matches)) { return fn.call(this._dom,sel) };
1962
- // TODO support other browsers etc?
1963
- };
1964
-
1965
- /*
1966
- Get the first element matching supplied selector / filter
1967
- traversing upwards, but including the node itself.
1968
- @return {Imba.Tag}
1969
- */
1970
-
1971
- tag.prototype.closest = function (sel){
1972
- if (!sel) { return this.parent() }; // should return self?!
1973
- var node = this;
1974
- if (sel.query) { sel = sel.query() };
1975
-
1976
- while (node){
1977
- if (node.matches(sel)) { return node };
1978
- node = node.parent();
1979
- };
1980
- return null;
1981
- };
1982
-
1983
- /*
1984
- Get the closest ancestor of node that matches
1985
- specified selector / matcher.
1986
-
1987
- @return {Imba.Tag}
1988
- */
1989
-
1990
- tag.prototype.up = function (sel){
1991
- if (!sel) { return this.parent() };
1992
- return this.parent() && this.parent().closest(sel);
1993
- };
1994
-
1995
- tag.prototype.path = function (sel){
1996
- var node = this;
1997
- var nodes = [];
1998
- if (sel && sel.query) { sel = sel.query() };
1999
-
2000
- while (node){
2001
- if (!sel || node.matches(sel)) { nodes.push(node) };
2002
- node = node.parent();
2003
- };
2004
- return nodes;
2005
- };
2006
-
2007
- tag.prototype.parents = function (sel){
2008
- var par = this.parent();
2009
- return par ? (par.path(sel)) : ([]);
2010
- };
2011
-
2012
-
2013
-
2014
- tag.prototype.siblings = function (sel){
2015
- var par, self = this;
2016
- if (!(par = this.parent())) { return [] }; // FIXME
2017
- var ary = this.dom().parentNode.children;
2018
- var nodes = new Imba.Selector(null,this,ary);
2019
- return nodes.filter(function(n) { return n != self && (!sel || n.matches(sel)); });
2020
- };
2021
-
2022
- /*
2023
- Get the immediately following sibling of node.
2024
- */
2025
-
2026
- tag.prototype.next = function (sel){
2027
- if (sel) {
2028
- var el = this;
2029
- while (el = el.next()){
2030
- if (el.matches(sel)) { return el };
2031
- };
2032
- return null;
2033
- };
2034
- return tag$wrap(this.dom().nextElementSibling);
2035
- };
2036
-
2037
- /*
2038
- Get the immediately preceeding sibling of node.
2039
- */
2040
-
2041
- tag.prototype.prev = function (sel){
2042
- if (sel) {
2043
- var el = this;
2044
- while (el = el.prev()){
2045
- if (el.matches(sel)) { return el };
2046
- };
2047
- return null;
2048
- };
2049
- return tag$wrap(this.dom().previousElementSibling);
2050
- };
2051
-
2052
- tag.prototype.contains = function (node){
2053
- return this.dom().contains(node && node._dom || node);
2054
- };
2055
-
2056
- tag.prototype.index = function (){
2057
- var i = 0;
2058
- var el = this.dom();
2059
- while (el.previousSibling){
2060
- el = el.previousSibling;
2061
- i++;
2062
- };
2063
- return i;
2064
- };
2065
-
2066
-
2067
- /*
2068
-
2069
- @deprecated
2070
- */
2071
-
2072
- tag.prototype.insert = function (node,pars){
2073
- if(!pars||pars.constructor !== Object) pars = {};
2074
- var before = pars.before !== undefined ? pars.before : null;
2075
- var after = pars.after !== undefined ? pars.after : null;
2076
- if (after) { before = after.next() };
2077
- if (node instanceof Array) {
2078
- node = (tag$.$fragment().setContent(node,0).end());
2079
- };
2080
- if (before) {
2081
- this.dom().insertBefore(node.dom(),before.dom());
2082
- } else {
2083
- this.append(node);
2084
- };
2085
- return this;
2086
- };
2087
-
2088
- /*
2089
- Focus on current node
2090
- @return {self}
2091
- */
2092
-
2093
- tag.prototype.focus = function (){
2094
- this.dom().focus();
2095
- return this;
2096
- };
2097
-
2098
- /*
2099
- Remove focus from current node
2100
- @return {self}
2101
- */
2102
-
2103
- tag.prototype.blur = function (){
2104
- this.dom().blur();
2105
- return this;
2106
- };
2107
-
2108
- tag.prototype.template = function (){
2109
- return null;
2110
- };
2111
-
2112
- /*
2113
- @todo Should support multiple arguments like append
2114
-
2115
- The .prepend method inserts the specified content as the first
2116
- child of the target node. If the content is already a child of
2117
- node it will be moved to the start.
2118
-
2119
- node.prepend <div.top> # prepend node
2120
- node.prepend "some text" # prepend text
2121
- node.prepend [<ul>,<ul>] # prepend array
2122
-
2123
- */
2124
-
2125
- tag.prototype.prepend = function (item){
2126
- var first = this._dom.childNodes[0];
2127
- first ? (this.insertBefore(item,first)) : (this.appendChild(item));
2128
- return this;
2129
- };
2130
-
2131
- /*
2132
- The .append method inserts the specified content as the last child
2133
- of the target node. If the content is already a child of node it
2134
- will be moved to the end.
2135
-
2136
- # example
2137
- var root = <div.root>
2138
- var item = <div.item> "This is an item"
2139
- root.append item # appends item to the end of root
2140
-
2141
- root.prepend "some text" # append text
2142
- root.prepend [<ul>,<ul>] # append array
2143
- */
2144
-
2145
- tag.prototype.append = function (item){
2146
- // possible to append blank
2147
- // possible to simplify on server?
2148
- if (!item) { return this };
2149
-
2150
- if (item instanceof Array) {
2151
- for (var i = 0, ary = iter$(item), len = ary.length, member; i < len; i++) {
2152
- member = ary[i];
2153
- member && this.append(member);
2154
- };
2155
- } else if ((typeof item=='string'||item instanceof String) || (typeof item=='number'||item instanceof Number)) {
2156
- var node = Imba.document().createTextNode(item);
2157
- this._dom.appendChild(node);
2158
- if (this._empty) { this._empty = false };
2159
- } else {
2160
- this._dom.appendChild(item._dom || item);
2161
- if (this._empty) { this._empty = false };
2162
- };
2163
-
2164
- return this;
2165
- };
2166
-
2167
- /*
2168
- Insert a node into the current node (self), before another.
2169
- The relative node must be a child of current node.
2170
- */
2171
-
2172
- tag.prototype.insertBefore = function (node,rel){
2173
- if ((typeof node=='string'||node instanceof String)) { node = Imba.document().createTextNode(node) };
2174
- if (node && rel) { this.dom().insertBefore((node._dom || node),(rel._dom || rel)) };
2175
- return this;
2176
- };
2177
-
2178
- /*
2179
- Append a single item (node or string) to the current node.
2180
- If supplied item is a string it will automatically. This is used
2181
- by Imba internally, but will practically never be used explicitly.
2182
- */
2183
-
2184
- tag.prototype.appendChild = function (node){
2185
- if ((typeof node=='string'||node instanceof String)) { node = Imba.document().createTextNode(node) };
2186
- if (node) { this.dom().appendChild(node._dom || node) };
2187
- return this;
2188
- };
2189
-
2190
- /*
2191
- Remove a single child from the current node.
2192
- Used by Imba internally.
2193
- */
2194
-
2195
- tag.prototype.removeChild = function (node){
2196
- if (node) { this.dom().removeChild(node._dom || node) };
2197
- return this;
2198
- };
2199
-
2200
- tag.prototype.toString = function (){
2201
- return this._dom.toString(); // really?
2202
- };
2203
-
2204
- /*
2205
- @deprecated
2206
- */
2207
-
2208
- tag.prototype.classes = function (){
2209
- console.log('Imba.Tag#classes is deprecated');
2210
- return this._dom.classList;
2211
- };
2212
- });
2213
-
2214
- return tag$.defineTag('svgelement', 'htmlelement');
2215
-
2216
- })()
2217
- },{}],7:[function(require,module,exports){
2218
- (function(){
2219
- if (!document.documentElement.classList) {
2220
- tag$.extendTag('htmlelement', function(tag){
2221
-
2222
- tag.prototype.hasFlag = function (ref){
2223
- return new RegExp('(^|\\s)' + ref + '(\\s|$)').test(this._dom.className);
2224
- };
2225
-
2226
- tag.prototype.addFlag = function (ref){
2227
- if (this.hasFlag(ref)) { return this };
2228
- this._dom.className += (this._dom.className ? (' ') : ('')) + ref;
2229
- return this;
2230
- };
2231
-
2232
- tag.prototype.unflag = function (ref){
2233
- if (!this.hasFlag(ref)) { return this };
2234
- var regex = new RegExp('(^|\\s)*' + ref + '(\\s|$)*','g');
2235
- this._dom.className = this._dom.className.replace(regex,'');
2236
- return this;
2237
- };
2238
-
2239
- tag.prototype.toggleFlag = function (ref){
2240
- return this.hasFlag(ref) ? (this.unflag(ref)) : (this.flag(ref));
2241
- };
2242
-
2243
- tag.prototype.flag = function (ref,bool){
2244
- if (arguments.length == 2 && !!bool === false) {
2245
- return this.unflag(ref);
2246
- };
2247
- return this.addFlag(ref);
2248
- };
2249
- });
2250
-
2251
- return true;
2252
- };
2253
-
2254
- })()
2255
- },{}],8:[function(require,module,exports){
2256
- (function(){
2257
- function iter$(a){ return a ? (a.toArray ? a.toArray() : a) : []; };
2258
- var ImbaTag = Imba.TAGS.element;
2259
-
2260
- function removeNested(root,node,caret){
2261
- // if node/nodes isa String
2262
- // we need to use the caret to remove elements
2263
- // for now we will simply not support this
2264
- if (node instanceof ImbaTag) {
2265
- root.removeChild(node);
2266
- } else if (node instanceof Array) {
2267
- for (var i = 0, ary = iter$(node), len = ary.length; i < len; i++) {
2268
- removeNested(root,ary[i],caret);
2269
- };
2270
- } else {
2271
- // what if this is not null?!?!?
2272
- // take a chance and remove a text-elementng
2273
- var next = caret ? (caret.nextSibling) : (root._dom.firstChild);
2274
- if ((next instanceof Text) && next.textContent == node) {
2275
- root.removeChild(next);
2276
- } else {
2277
- throw 'cannot remove string';
2278
- };
2279
- };
2280
-
2281
- return caret;
2282
- };
2283
-
2284
- function appendNested(root,node){
2285
- if (node instanceof ImbaTag) {
2286
- root.appendChild(node);
2287
- } else if (node instanceof Array) {
2288
- for (var i = 0, ary = iter$(node), len = ary.length; i < len; i++) {
2289
- appendNested(root,ary[i]);
2290
- };
2291
- } else if (node != null && node !== false) {
2292
- root.appendChild(Imba.document().createTextNode(node));
2293
- };
2294
-
2295
- return;
2296
- };
2297
-
2298
-
2299
- // insert nodes before a certain node
2300
- // does not need to return any tail, as before
2301
- // will still be correct there
2302
- // before must be an actual domnode
2303
- function insertNestedBefore(root,node,before){
2304
- if (node instanceof ImbaTag) {
2305
- root.insertBefore(node,before);
2306
- } else if (node instanceof Array) {
2307
- for (var i = 0, ary = iter$(node), len = ary.length; i < len; i++) {
2308
- insertNestedBefore(root,ary[i],before);
2309
- };
2310
- } else if (node != null && node !== false) {
2311
- root.insertBefore(Imba.document().createTextNode(node),before);
2312
- };
2313
-
2314
- return before;
2315
- };
2316
-
2317
- // after must be an actual domnode
2318
- function insertNestedAfter(root,node,after){
2319
- var before = after ? (after.nextSibling) : (root._dom.firstChild);
2320
-
2321
- if (before) {
2322
- insertNestedBefore(root,node,before);
2323
- return before.previousSibling;
2324
- } else {
2325
- appendNested(root,node);
2326
- return root._dom.lastChild;
2327
- };
2328
- };
2329
-
2330
- function reconcileCollectionChanges(root,new$,old,caret){
2331
-
2332
- var newLen = new$.length;
2333
- var lastNew = new$[newLen - 1];
2334
-
2335
- // This re-order algorithm is based on the following principle:
2336
- //
2337
- // We build a "chain" which shows which items are already sorted.
2338
- // If we're going from [1, 2, 3] -> [2, 1, 3], the tree looks like:
2339
- //
2340
- // 3 -> 0 (idx)
2341
- // 2 -> -1 (idx)
2342
- // 1 -> -1 (idx)
2343
- //
2344
- // This tells us that we have two chains of ordered items:
2345
- //
2346
- // (1, 3) and (2)
2347
- //
2348
- // The optimal re-ordering then becomes two keep the longest chain intact,
2349
- // and move all the other items.
2350
-
2351
- var newPosition = [];
2352
-
2353
- // The tree/graph itself
2354
- var prevChain = [];
2355
- // The length of the chain
2356
- var lengthChain = [];
2357
-
2358
- // Keep track of the longest chain
2359
- var maxChainLength = 0;
2360
- var maxChainEnd = 0;
2361
-
2362
- for (var idx = 0, ary = iter$(old), len = ary.length, node; idx < len; idx++) {
2363
- node = ary[idx];
2364
- var newPos = new$.indexOf(node);
2365
- newPosition.push(newPos);
2366
-
2367
- if (newPos == -1) {
2368
- root.removeChild(node);
2369
- prevChain.push(-1);
2370
- lengthChain.push(-1);
2371
- continue;
2372
- };
2373
-
2374
- var prevIdx = newPosition.length - 2;
2375
-
2376
- // Build the chain:
2377
- while (prevIdx >= 0){
2378
- if (newPosition[prevIdx] == -1) {
2379
- prevIdx--;
2380
- } else if (newPos > newPosition[prevIdx]) {
2381
- // Yay, we're bigger than the previous!
2382
- break;
2383
- } else {
2384
- // Nope, let's walk back the chain
2385
- prevIdx = prevChain[prevIdx];
2386
- };
2387
- };
2388
-
2389
- prevChain.push(prevIdx);
2390
-
2391
- var currLength = (prevIdx == -1) ? (0) : (lengthChain[prevIdx] + 1);
2392
-
2393
- if (currLength > maxChainLength) {
2394
- maxChainLength = currLength;
2395
- maxChainEnd = idx;
2396
- };
2397
-
2398
- lengthChain.push(currLength);
2399
- };
2400
-
2401
- var stickyNodes = [];
2402
-
2403
- // Now we can walk the longest chain backwards and mark them as "sticky",
2404
- // which implies that they should not be moved
2405
- var cursor = newPosition.length - 1;
2406
- while (cursor >= 0){
2407
- if (cursor == maxChainEnd && newPosition[cursor] != -1) {
2408
- stickyNodes[newPosition[cursor]] = true;
2409
- maxChainEnd = prevChain[maxChainEnd];
2410
- };
2411
-
2412
- cursor -= 1;
2413
- };
2414
-
2415
- // And let's iterate forward, but only move non-sticky nodes
2416
- for (var idx1 = 0, ary = iter$(new$), len = ary.length; idx1 < len; idx1++) {
2417
- if (!stickyNodes[idx1]) {
2418
- var after = new$[idx1 - 1];
2419
- insertNestedAfter(root,ary[idx1],(after && after._dom) || caret);
2420
- };
2421
- };
2422
-
2423
- // should trust that the last item in new list is the caret
2424
- return lastNew && lastNew._dom || caret;
2425
- };
2426
-
2427
-
2428
- // expects a flat non-sparse array of nodes in both new and old, always
2429
- function reconcileCollection(root,new$,old,caret){
2430
- var k = new$.length;
2431
- var i = k;
2432
- var last = new$[k - 1];
2433
-
2434
-
2435
- if (k == old.length && new$[0] === old[0]) {
2436
- // running through to compare
2437
- while (i--){
2438
- if (new$[i] !== old[i]) { break; };
2439
- };
2440
- };
2441
-
2442
- if (i == -1) {
2443
- return last && last._dom || caret;
2444
- } else {
2445
- return reconcileCollectionChanges(root,new$,old,caret);
2446
- };
2447
- };
2448
-
2449
- // the general reconciler that respects conditions etc
2450
- // caret is the current node we want to insert things after
2451
- function reconcileNested(root,new$,old,caret){
2452
-
2453
- // if new == null or new === false or new === true
2454
- // if new === old
2455
- // return caret
2456
- // if old && new != old
2457
- // removeNested(root,old,caret) if old
2458
- //
2459
- // return caret
2460
-
2461
- // var skipnew = new == null or new === false or new === true
2462
- var newIsNull = new$ == null || new$ === false;
2463
- var oldIsNull = old == null || old === false;
2464
-
2465
-
2466
- if (new$ === old) {
2467
- // remember that the caret must be an actual dom element
2468
- // we should instead move the actual caret? - trust
2469
- if (newIsNull) {
2470
- return caret;
2471
- } else if (new$ && new$._dom) {
2472
- return new$._dom;
2473
- } else {
2474
- return caret ? (caret.nextSibling) : (root._dom.firstChild);
2475
- };
2476
- } else if (new$ instanceof Array) {
2477
- if (old instanceof Array) {
2478
- if (new$.static || old.static) {
2479
- // if the static is not nested - we could get a hint from compiler
2480
- // and just skip it
2481
- if (new$.static == old.static) {
2482
- for (var i = 0, ary = iter$(new$), len = ary.length; i < len; i++) {
2483
- // this is where we could do the triple equal directly
2484
- caret = reconcileNested(root,ary[i],old[i],caret);
2485
- };
2486
- return caret;
2487
- } else {
2488
- removeNested(root,old,caret);
2489
- };
2490
-
2491
- // if they are not the same we continue through to the default
2492
- } else {
2493
- return reconcileCollection(root,new$,old,caret);
2494
- };
2495
- } else if (old instanceof ImbaTag) {
2496
- root.removeChild(old);
2497
- } else if (!oldIsNull) {
2498
- // old was a string-like object?
2499
- root.removeChild(caret ? (caret.nextSibling) : (root._dom.firstChild));
2500
- };
2501
-
2502
- return insertNestedAfter(root,new$,caret);
2503
- // remove old
2504
- } else if (new$ instanceof ImbaTag) {
2505
- if (!oldIsNull) { removeNested(root,old,caret) };
2506
- insertNestedAfter(root,new$,caret);
2507
- return new$;
2508
- } else if (newIsNull) {
2509
- if (!oldIsNull) { removeNested(root,old,caret) };
2510
- return caret;
2511
- } else {
2512
- // if old did not exist we need to add a new directly
2513
- var nextNode;
2514
- // if old was array or imbatag we need to remove it and then add
2515
- if (old instanceof Array) {
2516
- removeNested(root,old,caret);
2517
- } else if (old instanceof ImbaTag) {
2518
- root.removeChild(old);
2519
- } else if (!oldIsNull) {
2520
- // ...
2521
- nextNode = caret ? (caret.nextSibling) : (root._dom.firstChild);
2522
- if ((nextNode instanceof Text) && nextNode.textContent != new$) {
2523
- nextNode.textContent = new$;
2524
- return nextNode;
2525
- };
2526
- };
2527
-
2528
- // now add the textnode
2529
- return insertNestedAfter(root,new$,caret);
2530
- };
2531
- };
2532
-
2533
-
2534
- return tag$.extendTag('htmlelement', function(tag){
2535
-
2536
- tag.prototype.setChildren = function (new$,typ){
2537
- var old = this._children;
2538
- // var isArray = nodes isa Array
2539
- if (new$ === old) {
2540
- return this;
2541
- };
2542
-
2543
- if (!old) {
2544
- this.empty();
2545
- appendNested(this,new$);
2546
- } else if (typ == 2) {
2547
- return this;
2548
- } else if (typ == 1) {
2549
- // here we _know _that it is an array with the same shape
2550
- // every time
2551
- var caret = null;
2552
- for (var i = 0, ary = iter$(new$), len = ary.length; i < len; i++) {
2553
- // prev = old[i]
2554
- caret = reconcileNested(this,ary[i],old[i],caret);
2555
- };
2556
- } else if (typ == 3) {
2557
- // this is possibly fully dynamic. It often is
2558
- // but the old or new could be static while the other is not
2559
- // this is not handled now
2560
- // what if it was previously a static array? edgecase - but must work
2561
- if (new$ instanceof ImbaTag) {
2562
- this.empty();
2563
- this.appendChild(new$);
2564
- } else if (new$ instanceof Array) {
2565
- if (old instanceof Array) {
2566
- // is this not the same as setting staticChildren now but with the
2567
- reconcileCollection(this,new$,old,null);
2568
- } else {
2569
- this.empty();
2570
- appendNested(this,new$);
2571
- };
2572
- } else {
2573
- this.setText(new$);
2574
- return this;
2575
- };
2576
- } else if ((new$ instanceof Array) && (old instanceof Array)) {
2577
- reconcileCollection(this,new$,old,null);
2578
- } else {
2579
- this.empty();
2580
- appendNested(this,new$);
2581
- };
2582
-
2583
- this._children = new$;
2584
- return this;
2585
- };
2586
-
2587
-
2588
- // only ever called with array as argument
2589
- tag.prototype.setStaticChildren = function (new$){
2590
- var old = this._children;
2591
-
2592
- var caret = null;
2593
- for (var i = 0, ary = iter$(new$), len = ary.length; i < len; i++) {
2594
- // prev = old[i]
2595
- caret = reconcileNested(this,ary[i],old[i],caret);
2596
- };
2597
-
2598
- this._children = new$;
2599
- return this;
2600
- };
2601
-
2602
- tag.prototype.content = function (){
2603
- return this._content || this.children().toArray();
2604
- };
2605
-
2606
- tag.prototype.setText = function (text){
2607
- if (text != this._children) {
2608
- this._children = text;
2609
- this.dom().textContent = text == null || text === false ? ('') : (text);
2610
- };
2611
- return this;
2612
- };
2613
- });
2614
-
2615
- })()
2616
- },{}],9:[function(require,module,exports){
2617
- (function(){
2618
- function idx$(a,b){
2619
- return (b && b.indexOf) ? b.indexOf(a) : [].indexOf.call(a,b);
2620
- };
2621
-
2622
-
2623
- tag$.SVG.defineTag('svgelement', function(tag){
2624
-
2625
- tag.namespaceURI = function (){
2626
- return "http://www.w3.org/2000/svg";
2627
- };
2628
-
2629
- var types = "circle defs ellipse g line linearGradient mask path pattern polygon polyline radialGradient rect stop svg text tspan".split(" ");
2630
-
2631
- tag.buildNode = function (){
2632
- var dom = Imba.document().createElementNS(this.namespaceURI(),this._nodeType);
2633
- var cls = this._classes.join(" ");
2634
- if (cls) { dom.className.baseVal = cls };
2635
- return dom;
2636
- };
2637
-
2638
- tag.inherit = function (child){
2639
- child._protoDom = null;
2640
-
2641
- if (idx$(child._name,types) >= 0) {
2642
- child._nodeType = child._name;
2643
- return child._classes = [];
2644
- } else {
2645
- child._nodeType = this._nodeType;
2646
- var className = "_" + child._name.replace(/_/g,'-');
2647
- return child._classes = this._classes.concat(className);
2648
- };
2649
- };
2650
-
2651
-
2652
- Imba.attr(tag,'x');
2653
- Imba.attr(tag,'y');
2654
-
2655
- Imba.attr(tag,'width');
2656
- Imba.attr(tag,'height');
2657
-
2658
- Imba.attr(tag,'stroke');
2659
- Imba.attr(tag,'stroke-width');
2660
- });
2661
-
2662
- tag$.SVG.defineTag('svg', function(tag){
2663
- Imba.attr(tag,'viewbox');
2664
- });
2665
-
2666
- tag$.SVG.defineTag('rect');
2667
-
2668
- tag$.SVG.defineTag('circle', function(tag){
2669
- Imba.attr(tag,'cx');
2670
- Imba.attr(tag,'cy');
2671
- Imba.attr(tag,'r');
2672
- });
2673
-
2674
- tag$.SVG.defineTag('ellipse', function(tag){
2675
- Imba.attr(tag,'cx');
2676
- Imba.attr(tag,'cy');
2677
- Imba.attr(tag,'rx');
2678
- Imba.attr(tag,'ry');
2679
- });
2680
-
2681
- tag$.SVG.defineTag('path', function(tag){
2682
- Imba.attr(tag,'d');
2683
- Imba.attr(tag,'pathLength');
2684
- });
2685
-
2686
- return tag$.SVG.defineTag('line', function(tag){
2687
- Imba.attr(tag,'x1');
2688
- Imba.attr(tag,'x2');
2689
- Imba.attr(tag,'y1');
2690
- Imba.attr(tag,'y2');
2691
- });
2692
-
2693
- })()
2694
- },{}],10:[function(require,module,exports){
2695
- (function(){
2696
- // externs;
2697
-
2698
- if (typeof window !== 'undefined') {
2699
- global = window;
2700
- };
2701
-
2702
- /*
2703
- Imba is the namespace for all runtime related utilities
2704
- @namespace
2705
- */
2706
-
2707
- Imba = {
2708
- VERSION: '0.14.1',
2709
- DEBUG: false
2710
- };
2711
-
2712
- var reg = /-./g;
2713
-
2714
- /*
2715
- True if running in client environment.
2716
- @return {bool}
2717
- */
2718
-
2719
- Imba.isClient = function (){
2720
- return Imba.CLIENT === true;
2721
- };
2722
-
2723
- /*
2724
- True if running in server environment.
2725
- @return {bool}
2726
- */
2727
-
2728
- Imba.isServer = function (){
2729
- return Imba.SERVER === true;
2730
- };
2731
-
2732
- Imba.subclass = function (obj,sup){
2733
- ;
2734
- for (var k in sup){
2735
- if (sup.hasOwnProperty(k)) { obj[k] = sup[k] };
2736
- };
2737
-
2738
- obj.prototype = Object.create(sup.prototype);
2739
- obj.__super__ = obj.prototype.__super__ = sup.prototype;
2740
- obj.prototype.initialize = obj.prototype.constructor = obj;
2741
- return obj;
2742
- };
2743
-
2744
- /*
2745
- Lightweight method for making an object iterable in imbas for/in loops.
2746
- If the compiler cannot say for certain that a target in a for loop is an
2747
- array, it will cache the iterable version before looping.
2748
-
2749
- ```imba
2750
- # this is the whole method
2751
- def Imba.iterable o
2752
- return o ? (o:toArray ? o.toArray : o) : []
2753
-
2754
- class CustomIterable
2755
- def toArray
2756
- [1,2,3]
2757
-
2758
- # will return [2,4,6]
2759
- for x in CustomIterable.new
2760
- x * 2
2761
-
2762
- ```
2763
- */
2764
-
2765
- Imba.iterable = function (o){
2766
- return o ? ((o.toArray ? (o.toArray()) : (o))) : ([]);
2767
- };
2768
-
2769
- /*
2770
- Coerces a value into a promise. If value is array it will
2771
- call `Promise.all(value)`, or if it is not a promise it will
2772
- wrap the value in `Promise.resolve(value)`. Used for experimental
2773
- await syntax.
2774
- @return {Promise}
2775
- */
2776
-
2777
- Imba.await = function (value){
2778
- if (value instanceof Array) {
2779
- return Promise.all(value);
2780
- } else if (value && value.then) {
2781
- return value;
2782
- } else {
2783
- return Promise.resolve(value);
2784
- };
2785
- };
2786
-
2787
- Imba.toCamelCase = function (str){
2788
- return str.replace(reg,function(m) { return m.charAt(1).toUpperCase(); });
2789
- };
2790
-
2791
- Imba.toCamelCase = function (str){
2792
- return str.replace(reg,function(m) { return m.charAt(1).toUpperCase(); });
2793
- };
2794
-
2795
- Imba.indexOf = function (a,b){
2796
- return (b && b.indexOf) ? (b.indexOf(a)) : ([].indexOf.call(a,b));
2797
- };
2798
-
2799
- Imba.prop = function (scope,name,opts){
2800
- if (scope.defineProperty) {
2801
- return scope.defineProperty(name,opts);
2802
- };
2803
- return;
2804
- };
2805
-
2806
- return Imba.attr = function (scope,name,opts){
2807
- if (scope.defineAttribute) {
2808
- return scope.defineAttribute(name,opts);
2809
- };
2810
-
2811
- var getName = Imba.toCamelCase(name);
2812
- var setName = Imba.toCamelCase('set-' + name);
2813
-
2814
- scope.prototype[getName] = function() {
2815
- return this.getAttribute(name);
2816
- };
2817
-
2818
- scope.prototype[setName] = function(value) {
2819
- this.setAttribute(name,value);
2820
- return this;
2821
- };
2822
-
2823
- return;
2824
- };
2825
-
2826
- })()
2827
- },{}],11:[function(require,module,exports){
2828
- (function (global){
2829
- (function(){
2830
- function idx$(a,b){
2831
- return (b && b.indexOf) ? b.indexOf(a) : [].indexOf.call(a,b);
2832
- };
2833
-
2834
-
2835
- var raf; // very simple raf polyfill
2836
- raf || (raf = global.requestAnimationFrame);
2837
- raf || (raf = global.webkitRequestAnimationFrame);
2838
- raf || (raf = global.mozRequestAnimationFrame);
2839
- raf || (raf = function(blk) { return setTimeout(blk,1000 / 60); });
2840
-
2841
- Imba.tick = function (d){
2842
- if (this._scheduled) { raf(Imba.ticker()) };
2843
- this.emit(this,'tick',[d]);
2844
- return;
2845
- };
2846
-
2847
- Imba.ticker = function (){
2848
- var self = this;
2849
- return self._ticker || (self._ticker = function(e) { return self.tick(e); });
2850
- };
2851
-
2852
- /*
2853
-
2854
- Global alternative to requestAnimationFrame. Schedule a target
2855
- to tick every frame. You can specify which method to call on the
2856
- target (defaults to tick).
2857
-
2858
- */
2859
-
2860
- Imba.schedule = function (target,method){
2861
- if(method === undefined) method = 'tick';
2862
- this.listen(this,'tick',target,method);
2863
- // start scheduling now if this was the first one
2864
- if (!this._scheduled) {
2865
- this._scheduled = true;
2866
- raf(Imba.ticker());
2867
- };
2868
- return this;
2869
- };
2870
-
2871
- /*
2872
-
2873
- Unschedule a previously scheduled target
2874
-
2875
- */
2876
-
2877
- Imba.unschedule = function (target,method){
2878
- this.unlisten(this,'tick',target,method);
2879
- var cbs = this.__listeners__ || (this.__listeners__ = {});
2880
- if (!cbs.tick || !cbs.tick.next || !cbs.tick.next.listener) {
2881
- this._scheduled = false;
2882
- };
2883
- return this;
2884
- };
2885
-
2886
- /*
2887
-
2888
- Light wrapper around native setTimeout that expects the block / function
2889
- as last argument (instead of first). It also triggers an event to Imba
2890
- after the timeout to let schedulers update (to rerender etc) afterwards.
2891
-
2892
- */
2893
-
2894
- Imba.setTimeout = function (delay,block){
2895
- return setTimeout(function() {
2896
- block();
2897
- return Imba.emit(Imba,'timeout',[block]);
2898
- },delay);
2899
- };
2900
-
2901
- /*
2902
-
2903
- Light wrapper around native setInterval that expects the block / function
2904
- as last argument (instead of first). It also triggers an event to Imba
2905
- after every interval to let schedulers update (to rerender etc) afterwards.
2906
-
2907
- */
2908
-
2909
- Imba.setInterval = function (interval,block){
2910
- return setInterval(function() {
2911
- block();
2912
- return Imba.emit(Imba,'interval',[block]);
2913
- },interval);
2914
- };
2915
-
2916
- /*
2917
- Clear interval with specified id
2918
- */
2919
-
2920
- Imba.clearInterval = function (interval){
2921
- return clearInterval(interval);
2922
- };
2923
-
2924
- /*
2925
- Clear timeout with specified id
2926
- */
2927
-
2928
- Imba.clearTimeout = function (timeout){
2929
- return clearTimeout(timeout);
2930
- };
2931
-
2932
- // should add an Imba.run / setImmediate that
2933
- // pushes listener onto the tick-queue with times - once
2934
-
2935
-
2936
- /*
2937
-
2938
- Instances of Imba.Scheduler manages when to call `tick()` on their target,
2939
- at a specified framerate or when certain events occur. Root-nodes in your
2940
- applications will usually have a scheduler to make sure they rerender when
2941
- something changes. It is also possible to make inner components use their
2942
- own schedulers to control when they render.
2943
-
2944
- @iname scheduler
2945
-
2946
- */
2947
-
2948
- Imba.Scheduler = function Scheduler(target){
2949
- var self = this;
2950
- self._target = target;
2951
- self._marked = false;
2952
- self._active = false;
2953
- self._marker = function() { return self.mark(); };
2954
- self._ticker = function(e) { return self.tick(e); };
2955
-
2956
- self._events = true;
2957
- self._fps = 1;
2958
-
2959
- self._dt = 0;
2960
- self._timestamp = 0;
2961
- self._ticks = 0;
2962
- self._flushes = 0;
2963
- };
2964
-
2965
- /*
2966
- Create a new Imba.Scheduler for specified target
2967
- @return {Imba.Scheduler}
2968
- */
2969
-
2970
- /*
2971
- Check whether the current scheduler is active or not
2972
- @return {bool}
2973
- */
2974
-
2975
- Imba.Scheduler.prototype.active = function (){
2976
- return this._active;
2977
- };
2978
-
2979
- /*
2980
- Delta time between the two last ticks
2981
- @return {Number}
2982
- */
2983
-
2984
- Imba.Scheduler.prototype.dt = function (){
2985
- return this._dt;
2986
- };
2987
-
2988
- /*
2989
- Delta time between the two last ticks
2990
- @return {Number}
2991
- */
2992
-
2993
- Imba.Scheduler.prototype.configure = function (pars){
2994
- if(!pars||pars.constructor !== Object) pars = {};
2995
- var fps = pars.fps !== undefined ? pars.fps : 1;
2996
- var events = pars.events !== undefined ? pars.events : true;
2997
- if (events != null) { this._events = events };
2998
- if (fps != null) { this._fps = fps };
2999
- return this;
3000
- };
3001
-
3002
- // def reschedule
3003
- // raf(@ticker)
3004
- // self
3005
-
3006
- /*
3007
- Mark the scheduler as dirty. This will make sure that
3008
- the scheduler calls `target.tick` on the next frame
3009
- @return {self}
3010
- */
3011
-
3012
- Imba.Scheduler.prototype.mark = function (){
3013
- this._marked = true;
3014
- return this;
3015
- };
3016
-
3017
- /*
3018
- Instantly trigger target.tick and mark scheduler as clean (not dirty/marked).
3019
- This is called implicitly from tick, but can also be called manually if you
3020
- really want to force a tick without waiting for the next frame.
3021
- @return {self}
3022
- */
3023
-
3024
- Imba.Scheduler.prototype.flush = function (){
3025
- this._marked = false;
3026
- this._flushes++;
3027
- this._target.tick();
3028
- return this;
3029
- };
3030
-
3031
- /*
3032
- @fixme this expects raf to run at 60 fps
3033
-
3034
- Called automatically on every frame while the scheduler is active.
3035
- It will only call `target.tick` if the scheduler is marked dirty,
3036
- or when according to @fps setting.
3037
-
3038
- If you have set up a scheduler with an fps of 1, tick will still be
3039
- called every frame, but `target.tick` will only be called once every
3040
- second, and it will *make sure* each `target.tick` happens in separate
3041
- seconds according to Date. So if you have a node that renders a clock
3042
- based on Date.now (or something similar), you can schedule it with 1fps,
3043
- never needing to worry about two ticks happening within the same second.
3044
- The same goes for 4fps, 10fps etc.
3045
-
3046
- @protected
3047
- @return {self}
3048
- */
3049
-
3050
- Imba.Scheduler.prototype.tick = function (delta){
3051
- this._ticks++;
3052
- this._dt = delta;
3053
-
3054
- var fps = this._fps;
3055
-
3056
- if (fps == 60) {
3057
- this._marked = true;
3058
- } else if (fps == 30) {
3059
- if (this._ticks % 2) { this._marked = true };
3060
- } else if (fps) {
3061
- // if it is less round - we trigger based
3062
- // on date, for consistent rendering.
3063
- // ie, if you want to render every second
3064
- // it is important that no two renders
3065
- // happen during the same second (according to Date)
3066
- var period = ((60 / fps) / 60) * 1000;
3067
- var beat = Math.floor(Date.now() / period);
3068
-
3069
- if (this._beat != beat) {
3070
- this._beat = beat;
3071
- this._marked = true;
3072
- };
3073
- };
3074
-
3075
- if (this._marked) this.flush();
3076
- // reschedule if @active
3077
- return this;
3078
- };
3079
-
3080
- /*
3081
- Start the scheduler if it is not already active.
3082
- **While active**, the scheduler will override `target.commit`
3083
- to do nothing. By default Imba.tag#commit calls render, so
3084
- that rendering is cascaded through to children when rendering
3085
- a node. When a scheduler is active (for a node), Imba disables
3086
- this automatic rendering.
3087
- */
3088
-
3089
- Imba.Scheduler.prototype.activate = function (){
3090
- if (!this._active) {
3091
- this._active = true;
3092
- // override target#commit while this is active
3093
- this._commit = this._target.commit;
3094
- this._target.commit = function() { return this; };
3095
- Imba.schedule(this);
3096
- if (this._events) { Imba.listen(Imba,'event',this,'onevent') };
3097
- this._target && this._target.flag && this._target.flag('scheduled_');
3098
- this.tick(0); // start ticking
3099
- };
3100
- return this;
3101
- };
3102
-
3103
- /*
3104
- Stop the scheduler if it is active.
3105
- */
3106
-
3107
- Imba.Scheduler.prototype.deactivate = function (){
3108
- if (this._active) {
3109
- this._active = false;
3110
- this._target.commit = this._commit;
3111
- Imba.unschedule(this);
3112
- Imba.unlisten(Imba,'event',this);
3113
- this._target && this._target.unflag && this._target.unflag('scheduled_');
3114
- };
3115
- return this;
3116
- };
3117
-
3118
- Imba.Scheduler.prototype.track = function (){
3119
- return this._marker;
3120
- };
3121
-
3122
- Imba.Scheduler.prototype.onevent = function (event){
3123
- var $1;
3124
- if (this._marked) { return this };
3125
-
3126
- if (this._events instanceof Function) {
3127
- if (this._events(event)) this.mark();
3128
- } else if (this._events instanceof Array) {
3129
- if (idx$(($1 = event) && $1.type && $1.type(),this._events) >= 0) this.mark();
3130
- } else if (this._events) {
3131
- if (event._responder) this.mark();
3132
- };
3133
- return this;
3134
- };
3135
- return Imba.Scheduler;
3136
-
3137
- })()
3138
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
3139
- },{}],12:[function(require,module,exports){
3140
- (function(){
3141
- function iter$(a){ return a ? (a.toArray ? a.toArray() : a) : []; };
3142
-
3143
- /*
3144
- The special syntax for selectors in Imba creates Imba.Selector
3145
- instances.
3146
- */
3147
-
3148
- Imba.Selector = function Selector(sel,scope,nodes){
3149
-
3150
- this._query = sel instanceof Imba.Selector ? (sel.query()) : (sel);
3151
- this._context = scope;
3152
-
3153
- if (nodes) {
3154
- for (var i = 0, ary = iter$(nodes), len = ary.length, res = []; i < len; i++) {
3155
- res.push(tag$wrap(ary[i]));
3156
- };
3157
- this._nodes = res;
3158
- };
3159
-
3160
- this._lazy = !nodes;
3161
- return this;
3162
- };
3163
-
3164
- Imba.Selector.one = function (sel,scope){
3165
- var el = (scope || Imba.document()).querySelector(sel);
3166
- return el && tag$wrap(el) || null;
3167
- };
3168
-
3169
- Imba.Selector.all = function (sel,scope){
3170
- return new Imba.Selector(sel,scope);
3171
- };
3172
-
3173
-
3174
-
3175
- Imba.Selector.prototype.query = function(v){ return this._query; }
3176
- Imba.Selector.prototype.setQuery = function(v){ this._query = v; return this; };
3177
-
3178
- Imba.Selector.prototype.reload = function (){
3179
- this._nodes = null;
3180
- return this;
3181
- };
3182
-
3183
- Imba.Selector.prototype.scope = function (){
3184
- var ctx;
3185
- if (this._scope) { return this._scope };
3186
- if (!(ctx = this._context)) { return Imba.document() };
3187
- return this._scope = ctx.toScope ? (ctx.toScope()) : (ctx);
3188
- };
3189
-
3190
- /*
3191
- @returns {Imba.Tag} first node matching this selector
3192
- */
3193
-
3194
- Imba.Selector.prototype.first = function (){
3195
- if (this._lazy) { return tag$wrap(this._first || (this._first = this.scope().querySelector(this.query()))) } else {
3196
- return this.nodes()[0];
3197
- };
3198
- };
3199
-
3200
- /*
3201
- @returns {Imba.Tag} last node matching this selector
3202
- */
3203
-
3204
- Imba.Selector.prototype.last = function (){
3205
- return this.nodes()[this._nodes.length - 1];
3206
- };
3207
-
3208
- /*
3209
- @returns [Imba.Tag] all nodes matching this selector
3210
- */
3211
-
3212
- Imba.Selector.prototype.nodes = function (){
3213
- if (this._nodes) { return this._nodes };
3214
- var items = this.scope().querySelectorAll(this.query());
3215
- for (var i = 0, ary = iter$(items), len = ary.length, res = []; i < len; i++) {
3216
- res.push(tag$wrap(ary[i]));
3217
- };
3218
- this._nodes = res;
3219
- this._lazy = false;
3220
- return this._nodes;
3221
- };
3222
-
3223
- /*
3224
- The number of nodes matching this selector
3225
- */
3226
-
3227
- Imba.Selector.prototype.count = function (){
3228
- return this.nodes().length;
3229
- };
3230
-
3231
- Imba.Selector.prototype.len = function (){
3232
- return this.nodes().length;
3233
- };
3234
-
3235
- /*
3236
- @todo Add support for block or selector?
3237
- */
3238
-
3239
- Imba.Selector.prototype.some = function (){
3240
- return this.count() >= 1;
3241
- };
3242
-
3243
- /*
3244
- Get node at index
3245
- */
3246
-
3247
- Imba.Selector.prototype.at = function (idx){
3248
- return this.nodes()[idx];
3249
- };
3250
-
3251
- /*
3252
- Loop through nodes
3253
- */
3254
-
3255
- Imba.Selector.prototype.forEach = function (block){
3256
- this.nodes().forEach(block);
3257
- return this;
3258
- };
3259
-
3260
- /*
3261
- Map nodes
3262
- */
3263
-
3264
- Imba.Selector.prototype.map = function (block){
3265
- return this.nodes().map(block);
3266
- };
3267
-
3268
- /*
3269
- Returns a plain array containing nodes. Implicitly called
3270
- when iterating over a selector in Imba `(node for node in $(selector))`
3271
- */
3272
-
3273
- Imba.Selector.prototype.toArray = function (){
3274
- return this.nodes();
3275
- };
3276
-
3277
- // Get the first element that matches the selector,
3278
- // beginning at the current element and progressing up through the DOM tree
3279
- Imba.Selector.prototype.closest = function (sel){
3280
- // seems strange that we alter this selector?
3281
- this._nodes = this.map(function(node) { return node.closest(sel); });
3282
- return this;
3283
- };
3284
-
3285
- // Get the siblings of each element in the set of matched elements,
3286
- // optionally filtered by a selector.
3287
- // TODO remove duplicates?
3288
- Imba.Selector.prototype.siblings = function (sel){
3289
- this._nodes = this.map(function(node) { return node.siblings(sel); });
3290
- return this;
3291
- };
3292
-
3293
- // Get the descendants of each element in the current set of matched
3294
- // elements, filtered by a selector.
3295
- Imba.Selector.prototype.find = function (sel){
3296
- this._nodes = this.__query__(sel.query(),this.nodes());
3297
- return this;
3298
- };
3299
-
3300
- Imba.Selector.prototype.reject = function (blk){
3301
- return this.filter(blk,false);
3302
- };
3303
-
3304
- /*
3305
- Filter the nodes in selector by a function or other selector
3306
- */
3307
-
3308
- Imba.Selector.prototype.filter = function (blk,bool){
3309
- if(bool === undefined) bool = true;
3310
- var fn = (blk instanceof Function) && blk || function(n) { return n.matches(blk); };
3311
- var ary = this.nodes().filter(function(n) { return fn(n) == bool; });
3312
- // if we want to return a new selector for this, we should do that for
3313
- // others as well
3314
- return new Imba.Selector("",this._scope,ary);
3315
- };
3316
-
3317
- Imba.Selector.prototype.__query__ = function (query,contexts){
3318
- var nodes = [];
3319
- var i = 0;
3320
- var l = contexts.length;
3321
-
3322
- while (i < l){
3323
- nodes.push.apply(nodes,contexts[i++].querySelectorAll(query));
3324
- };
3325
- return nodes;
3326
- };
3327
-
3328
- Imba.Selector.prototype.__matches__ = function (){
3329
- return true;
3330
- };
3331
-
3332
- /*
3333
- Add specified flag to all nodes in selector
3334
- */
3335
-
3336
- Imba.Selector.prototype.flag = function (flag){
3337
- return this.forEach(function(n) { return n.flag(flag); });
3338
- };
3339
-
3340
- /*
3341
- Remove specified flag from all nodes in selector
3342
- */
3343
-
3344
- Imba.Selector.prototype.unflag = function (flag){
3345
- return this.forEach(function(n) { return n.unflag(flag); });
3346
- };
3347
-
3348
-
3349
- // def Imba.querySelectorAll
3350
- q$ = function(sel,scope) { return new Imba.Selector(sel,scope); };
3351
-
3352
- // def Imba.Selector.one
3353
- q$$ = function(sel,scope) {
3354
- var el = (scope || Imba.document()).querySelector(sel);
3355
- return el && tag$wrap(el) || null;
3356
- };
3357
-
3358
-
3359
- // extending tags with query-methods
3360
- // must be a better way to reopen classes
3361
- return tag$.extendTag('element', function(tag){
3362
- tag.prototype.querySelectorAll = function (q){
3363
- return this._dom.querySelectorAll(q);
3364
- };
3365
- tag.prototype.querySelector = function (q){
3366
- return this._dom.querySelector(q);
3367
- };
3368
-
3369
- // should be moved to Imba.Tag instead?
3370
- // or we should implement all of them here
3371
- tag.prototype.find = function (sel){
3372
- return new Imba.Selector(sel,this);
3373
- };
3374
- });
3375
-
3376
-
3377
- })()
3378
- },{}],13:[function(require,module,exports){
3379
- (function(){
3380
- function idx$(a,b){
3381
- return (b && b.indexOf) ? b.indexOf(a) : [].indexOf.call(a,b);
3382
- };
3383
-
3384
- Imba.static = function (items,nr){
3385
- items.static = nr;
3386
- return items;
3387
- };
3388
-
3389
- /*
3390
- This is the baseclass that all tags in imba inherit from.
3391
- @iname node
3392
- */
3393
-
3394
- Imba.Tag = function Tag(dom){
3395
- this.setDom(dom);
3396
- };
3397
-
3398
- Imba.Tag.createNode = function (){
3399
- throw "Not implemented";
3400
- };
3401
-
3402
- Imba.Tag.build = function (){
3403
- return new this(this.createNode());
3404
- };
3405
-
3406
-
3407
-
3408
- Imba.Tag.prototype.object = function(v){ return this._object; }
3409
- Imba.Tag.prototype.setObject = function(v){ this._object = v; return this; };
3410
-
3411
- Imba.Tag.prototype.dom = function (){
3412
- return this._dom;
3413
- };
3414
-
3415
- Imba.Tag.prototype.setDom = function (dom){
3416
- dom._tag = this;
3417
- this._dom = dom;
3418
- return this;
3419
- };
3420
-
3421
- /*
3422
- Setting references for tags like
3423
- `<div@header>` will compile to `tag('div').setRef('header',this).end()`
3424
- By default it adds the reference as a className to the tag.
3425
- @return {self}
3426
- */
3427
-
3428
- Imba.Tag.prototype.setRef = function (ref,ctx){
3429
- this.flag(this._ref = ref);
3430
- return this;
3431
- };
3432
-
3433
- /*
3434
- Method that is called by the compiled tag-chains, for
3435
- binding events on tags to methods etc.
3436
- `<a :tap=fn>` compiles to `tag('a').setHandler('tap',fn,this).end()`
3437
- where this refers to the context in which the tag is created.
3438
- @return {self}
3439
- */
3440
-
3441
- Imba.Tag.prototype.setHandler = function (event,handler,ctx){
3442
- var key = 'on' + event;
3443
-
3444
- if (handler instanceof Function) {
3445
- this[key] = handler;
3446
- } else if (handler instanceof Array) {
3447
- var fn = handler.shift();
3448
- this[key] = function(e) { return ctx[fn].apply(ctx,handler.concat(e)); };
3449
- } else {
3450
- this[key] = function(e) { return ctx[handler](e); };
3451
- };
3452
- return this;
3453
- };
3454
-
3455
- Imba.Tag.prototype.setId = function (id){
3456
- this.dom().id = id;
3457
- return this;
3458
- };
3459
-
3460
- Imba.Tag.prototype.id = function (){
3461
- return this.dom().id;
3462
- };
3463
-
3464
- /*
3465
- Adds a new attribute or changes the value of an existing attribute
3466
- on the specified tag. If the value is null or false, the attribute
3467
- will be removed.
3468
- @return {self}
3469
- */
3470
-
3471
- Imba.Tag.prototype.setAttribute = function (name,value){
3472
- // should this not return self?
3473
- var old = this.dom().getAttribute(name);
3474
-
3475
- if (old == value) {
3476
- return value;
3477
- } else if (value != null && value !== false) {
3478
- return this.dom().setAttribute(name,value);
3479
- } else {
3480
- return this.dom().removeAttribute(name);
3481
- };
3482
- };
3483
-
3484
- /*
3485
- removes an attribute from the specified tag
3486
- */
3487
-
3488
- Imba.Tag.prototype.removeAttribute = function (name){
3489
- return this.dom().removeAttribute(name);
3490
- };
3491
-
3492
- /*
3493
- returns the value of an attribute on the tag.
3494
- If the given attribute does not exist, the value returned
3495
- will either be null or "" (the empty string)
3496
- */
3497
-
3498
- Imba.Tag.prototype.getAttribute = function (name){
3499
- return this.dom().getAttribute(name);
3500
- };
3501
-
3502
- /*
3503
- Override this to provide special wrapping etc.
3504
- @return {self}
3505
- */
3506
-
3507
- Imba.Tag.prototype.setContent = function (content,type){
3508
- this.setChildren(content,type);
3509
- return this;
3510
- };
3511
-
3512
- /*
3513
- Set the children of node. type param is optional,
3514
- and should only be used by Imba when compiling tag trees.
3515
- @return {self}
3516
- */
3517
-
3518
- Imba.Tag.prototype.setChildren = function (nodes,type){
3519
- throw "Not implemented";
3520
- };
3521
-
3522
- /*
3523
- Get text of node. Uses textContent behind the scenes (not innerText)
3524
- [https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent]()
3525
- @return {string} inner text of node
3526
- */
3527
-
3528
- Imba.Tag.prototype.text = function (v){
3529
- return this._dom.textContent;
3530
- };
3531
-
3532
- /*
3533
- Set text of node. Uses textContent behind the scenes (not innerText)
3534
- [https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent]()
3535
- */
3536
-
3537
- Imba.Tag.prototype.setText = function (txt){
3538
- this._empty = false;
3539
- this._dom.textContent = txt == null ? (txt = "") : (txt);
3540
- return this;
3541
- };
3542
-
3543
-
3544
- /*
3545
- Method for getting and setting data-attributes. When called with zero
3546
- arguments it will return the actual dataset for the tag.
3547
-
3548
- var node = <div data-name='hello'>
3549
- # get the whole dataset
3550
- node.dataset # {name: 'hello'}
3551
- # get a single value
3552
- node.dataset('name') # 'hello'
3553
- # set a single value
3554
- node.dataset('name','newname') # self
3555
-
3556
-
3557
- */
3558
-
3559
- Imba.Tag.prototype.dataset = function (key,val){
3560
- throw "Not implemented";
3561
- };
3562
-
3563
- /*
3564
- Empty placeholder. Override to implement custom render behaviour.
3565
- Works much like the familiar render-method in React.
3566
- @return {self}
3567
- */
3568
-
3569
- Imba.Tag.prototype.render = function (){
3570
- return this;
3571
- };
3572
-
3573
- /*
3574
- Called implicitly through Imba.Tag#end, upon creating a tag. All
3575
- properties will have been set before build is called, including
3576
- setContent.
3577
- @return {self}
3578
- */
3579
-
3580
- Imba.Tag.prototype.build = function (){
3581
- this.render();
3582
- return this;
3583
- };
3584
-
3585
- /*
3586
- Called implicitly through Imba.Tag#end, for tags that are part of
3587
- a tag tree (that are rendered several times).
3588
- @return {self}
3589
- */
3590
-
3591
- Imba.Tag.prototype.commit = function (){
3592
- this.render();
3593
- return this;
3594
- };
3595
-
3596
- /*
3597
-
3598
- Called by the tag-scheduler (if this tag is scheduled)
3599
- By default it will call this.render. Do not override unless
3600
- you really understand it.
3601
-
3602
- */
3603
-
3604
- Imba.Tag.prototype.tick = function (){
3605
- this.render();
3606
- return this;
3607
- };
3608
-
3609
- /*
3610
-
3611
- A very important method that you will practically never manually.
3612
- The tag syntax of Imba compiles to a chain of setters, which always
3613
- ends with .end. `<a.large>` compiles to `tag('a').flag('large').end()`
3614
-
3615
- You are highly adviced to not override its behaviour. The first time
3616
- end is called it will mark the tag as built and call Imba.Tag#build,
3617
- and call Imba.Tag#commit on subsequent calls.
3618
- @return {self}
3619
- */
3620
-
3621
- Imba.Tag.prototype.end = function (){
3622
- if (this._built) {
3623
- this.commit();
3624
- } else {
3625
- this._built = true;
3626
- this.build();
3627
- };
3628
- return this;
3629
- };
3630
-
3631
- /*
3632
- This is called instead of Imba.Tag#end for `<self>` tag chains.
3633
- Defaults to noop
3634
- @return {self}
3635
- */
3636
-
3637
- Imba.Tag.prototype.synced = function (){
3638
- return this;
3639
- };
3640
-
3641
- // called when the node is awakened in the dom - either automatically
3642
- // upon attachment to the dom-tree, or the first time imba needs the
3643
- // tag for a domnode that has been rendered on the server
3644
- Imba.Tag.prototype.awaken = function (){
3645
- return this;
3646
- };
3647
-
3648
- /*
3649
- List of flags for this node.
3650
- */
3651
-
3652
- Imba.Tag.prototype.flags = function (){
3653
- return this._dom.classList;
3654
- };
3655
-
3656
- /*
3657
- Add speficied flag to current node.
3658
- If a second argument is supplied, it will be coerced into a Boolean,
3659
- and used to indicate whether we should remove the flag instead.
3660
- @return {self}
3661
- */
3662
-
3663
- Imba.Tag.prototype.flag = function (name,toggler){
3664
- // it is most natural to treat a second undefined argument as a no-switch
3665
- // so we need to check the arguments-length
3666
- if (arguments.length == 2 && !toggler) {
3667
- this._dom.classList.remove(name);
3668
- } else {
3669
- this._dom.classList.add(name);
3670
- };
3671
- return this;
3672
- };
3673
-
3674
- /*
3675
- Remove specified flag from node
3676
- @return {self}
3677
- */
3678
-
3679
- Imba.Tag.prototype.unflag = function (name){
3680
- this._dom.classList.remove(name);
3681
- return this;
3682
- };
3683
-
3684
- /*
3685
- Toggle specified flag on node
3686
- @return {self}
3687
- */
3688
-
3689
- Imba.Tag.prototype.toggleFlag = function (name){
3690
- this._dom.classList.toggle(name);
3691
- return this;
3692
- };
3693
-
3694
- /*
3695
- Check whether current node has specified flag
3696
- @return {bool}
3697
- */
3698
-
3699
- Imba.Tag.prototype.hasFlag = function (name){
3700
- return this._dom.classList.contains(name);
3701
- };
3702
-
3703
- /*
3704
- Get the scheduler for this node. A new scheduler will be created
3705
- if it does not already exist.
3706
-
3707
- @return {Imba.Scheduler}
3708
- */
3709
-
3710
- Imba.Tag.prototype.scheduler = function (){
3711
- return this._scheduler == null ? (this._scheduler = new Imba.Scheduler(this)) : (this._scheduler);
3712
- };
3713
-
3714
- /*
3715
-
3716
- Shorthand to start scheduling a node. The method will basically
3717
- proxy the arguments through to scheduler.configure, and then
3718
- activate the scheduler.
3719
-
3720
- @return {self}
3721
- */
3722
-
3723
- Imba.Tag.prototype.schedule = function (options){
3724
- if(options === undefined) options = {};
3725
- this.scheduler().configure(options).activate();
3726
- return this;
3727
- };
3728
-
3729
- /*
3730
- Shorthand for deactivating scheduler (if tag has one).
3731
- @deprecated
3732
- */
3733
-
3734
- Imba.Tag.prototype.unschedule = function (){
3735
- if (this._scheduler) { this.scheduler().deactivate() };
3736
- return this;
3737
- };
3738
-
3739
-
3740
- /*
3741
- Get the parent of current node
3742
- @return {Imba.Tag}
3743
- */
3744
-
3745
- Imba.Tag.prototype.parent = function (){
3746
- return tag$wrap(this.dom().parentNode);
3747
- };
3748
-
3749
- /*
3750
- Shorthand for console.log on elements
3751
- @return {self}
3752
- */
3753
-
3754
- Imba.Tag.prototype.log = function (){
3755
- var $0 = arguments, i = $0.length;
3756
- var args = new Array(i>0 ? i : 0);
3757
- while(i>0) args[i-1] = $0[--i];
3758
- args.unshift(console);
3759
- Function.prototype.call.apply(console.log,args);
3760
- return this;
3761
- };
3762
-
3763
-
3764
- Imba.Tag.prototype.initialize = Imba.Tag;
3765
-
3766
- HTML_TAGS = "a abbr address area article aside audio b base bdi bdo big blockquote body br button canvas caption cite code col colgroup data datalist dd del details dfn div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header hr html i iframe img input ins kbd keygen label legend li link main map mark menu menuitem meta meter nav noscript object ol optgroup option output p param pre progress q rp rt ruby s samp script section select small source span strong style sub summary sup table tbody td textarea tfoot th thead time title tr track u ul var video wbr".split(" ");
3767
- HTML_TAGS_UNSAFE = "article aside header section".split(" ");
3768
- SVG_TAGS = "circle defs ellipse g line linearGradient mask path pattern polygon polyline radialGradient rect stop svg text tspan".split(" ");
3769
-
3770
-
3771
- function extender(obj,sup){
3772
- for (var i = 0, keys = Object.keys(sup), l = keys.length; i < l; i++){
3773
- obj[($1 = keys[i])] == null ? (obj[$1] = sup[keys[i]]) : (obj[$1]);
3774
- };
3775
-
3776
- obj.prototype = Object.create(sup.prototype);
3777
- obj.__super__ = obj.prototype.__super__ = sup.prototype;
3778
- obj.prototype.initialize = obj.prototype.constructor = obj;
3779
- if (sup.inherit) { sup.inherit(obj) };
3780
- return obj;
3781
- };
3782
-
3783
- function Tag(){
3784
- return function(dom) {
3785
- this.setDom(dom);
3786
- return this;
3787
- };
3788
- };
3789
-
3790
- function TagSpawner(type){
3791
- return function() { return type.build(); };
3792
- };
3793
-
3794
- Imba.Tags = function Tags(){
3795
- this;
3796
- };
3797
-
3798
- Imba.Tags.prototype.__clone = function (ns){
3799
- var clone = Object.create(this);
3800
- clone._parent = this;
3801
- return clone;
3802
- };
3803
-
3804
- Imba.Tags.prototype.defineNamespace = function (name){
3805
- var clone = Object.create(this);
3806
- clone._parent = this;
3807
- clone._ns = name;
3808
- this[name.toUpperCase()] = clone;
3809
- return clone;
3810
- };
3811
-
3812
- Imba.Tags.prototype.baseType = function (name){
3813
- return idx$(name,HTML_TAGS) >= 0 ? ('htmlelement') : ('div');
3814
- };
3815
-
3816
- Imba.Tags.prototype.defineTag = function (name,supr,body){
3817
- if(body==undefined && typeof supr == 'function') body = supr,supr = '';
3818
- if(supr==undefined) supr = '';
3819
- supr || (supr = this.baseType(name));
3820
- var supertype = this[supr];
3821
- var tagtype = Tag();
3822
- var norm = name.replace(/\-/g,'_');
3823
-
3824
-
3825
- tagtype._name = name;
3826
- extender(tagtype,supertype);
3827
-
3828
- if (name[0] == '#') {
3829
- this[name] = tagtype;
3830
- Imba.SINGLETONS[name.slice(1)] = tagtype;
3831
- } else {
3832
- this[name] = tagtype;
3833
- this['$' + norm] = TagSpawner(tagtype);
3834
- };
3835
-
3836
- if (body) {
3837
- if (body.length == 2) {
3838
- // create clone
3839
- if (!tagtype.hasOwnProperty('TAGS')) {
3840
- tagtype.TAGS = (supertype.TAGS || this).__clone();
3841
- };
3842
- };
3843
-
3844
- body.call(tagtype,tagtype,tagtype.TAGS || this);
3845
- };
3846
-
3847
- return tagtype;
3848
- };
3849
-
3850
- Imba.Tags.prototype.defineSingleton = function (name,supr,body){
3851
- return this.defineTag(name,supr,body);
3852
- };
3853
-
3854
- Imba.Tags.prototype.extendTag = function (name,supr,body){
3855
- if(body==undefined && typeof supr == 'function') body = supr,supr = '';
3856
- if(supr==undefined) supr = '';
3857
- var klass = ((typeof name=='string'||name instanceof String) ? (this[name]) : (name));
3858
- // allow for private tags here as well?
3859
- if (body) { body && body.call(klass,klass,klass.prototype) };
3860
- return klass;
3861
- };
3862
-
3863
-
3864
- Imba.TAGS = new Imba.Tags();
3865
- Imba.TAGS.element = Imba.Tag;
3866
-
3867
- var svg = Imba.TAGS.defineNamespace('svg');
3868
-
3869
- svg.baseType = function (name){
3870
- return 'svgelement';
3871
- };
3872
-
3873
-
3874
- Imba.SINGLETONS = {};
3875
-
3876
-
3877
- Imba.defineTag = function (name,supr,body){
3878
- if(body==undefined && typeof supr == 'function') body = supr,supr = '';
3879
- if(supr==undefined) supr = '';
3880
- return Imba.TAGS.defineTag(name,supr,body);
3881
- };
3882
-
3883
- Imba.defineSingletonTag = function (id,supr,body){
3884
- if(body==undefined && typeof supr == 'function') body = supr,supr = 'div';
3885
- if(supr==undefined) supr = 'div';
3886
- return Imba.TAGS.defineTag(this.name(),supr,body);
3887
- };
3888
-
3889
- Imba.extendTag = function (name,body){
3890
- return Imba.TAGS.extendTag(name,body);
3891
- };
3892
-
3893
- Imba.tag = function (name){
3894
- var typ = Imba.TAGS[name];
3895
- if (!typ) { throw new Error(("tag " + name + " is not defined")) };
3896
- return new typ(typ.createNode());
3897
- };
3898
-
3899
- Imba.tagWithId = function (name,id){
3900
- var typ = Imba.TAGS[name];
3901
- if (!typ) { throw new Error(("tag " + name + " is not defined")) };
3902
- var dom = typ.createNode();
3903
- dom.id = id;
3904
- return new typ(dom);
3905
- };
3906
-
3907
- // TODO: Can we move these out and into dom.imba in a clean way?
3908
- // These methods depends on Imba.document.getElementById
3909
-
3910
- Imba.getTagSingleton = function (id){
3911
- var klass;
3912
- var dom,node;
3913
-
3914
- if (klass = Imba.SINGLETONS[id]) {
3915
- if (klass && klass.Instance) { return klass.Instance };
3916
-
3917
- // no instance - check for element
3918
- if (dom = Imba.document().getElementById(id)) {
3919
- // we have a live instance - when finding it through a selector we should awake it, no?
3920
- // console.log('creating the singleton from existing node in dom?',id,type)
3921
- node = klass.Instance = new klass(dom);
3922
- node.awaken(dom); // should only awaken
3923
- return node;
3924
- };
3925
-
3926
- dom = klass.createNode();
3927
- dom.id = id;
3928
- node = klass.Instance = new klass(dom);
3929
- node.end().awaken(dom);
3930
- return node;
3931
- } else if (dom = Imba.document().getElementById(id)) {
3932
- return Imba.getTagForDom(dom);
3933
- };
3934
- };
3935
-
3936
- var svgSupport = typeof SVGElement !== 'undefined';
3937
-
3938
- Imba.getTagForDom = function (dom){
3939
- var m;
3940
- if (!dom) { return null };
3941
- if (dom._dom) { return dom }; // could use inheritance instead
3942
- if (dom._tag) { return dom._tag };
3943
- if (!dom.nodeName) { return null };
3944
-
3945
- var ns = null;
3946
- var id = dom.id;
3947
- var type = dom.nodeName.toLowerCase();
3948
- var tags = Imba.TAGS;
3949
- var native$ = type;
3950
- var cls = dom.className;
3951
-
3952
- if (id && Imba.SINGLETONS[id]) {
3953
- // FIXME control that it is the same singleton?
3954
- // might collide -- not good?
3955
- return Imba.getTagSingleton(id);
3956
- };
3957
- // look for id - singleton
3958
-
3959
- // need better test here
3960
- if (svgSupport && (dom instanceof SVGElement)) {
3961
- ns = "svg";
3962
- cls = dom.className.baseVal;
3963
- tags = tags.SVG;
3964
- };
3965
-
3966
- var spawner;
3967
-
3968
- if (cls) {
3969
- // there can be several matches here - should choose the last
3970
- // should fall back to less specific later? - otherwise things may fail
3971
- // TODO rework this
3972
- if (m = cls.match(/\b_([a-z\-]+)\b(?!\s*_[a-z\-]+)/)) {
3973
- type = m[1]; // .replace(/-/g,'_')
3974
- };
3975
-
3976
- if (m = cls.match(/\b([A-Z\-]+)_\b/)) {
3977
- ns = m[1];
3978
- };
3979
- };
3980
-
3981
-
3982
- spawner = tags[type] || tags[native$];
3983
- return spawner ? (new spawner(dom).awaken(dom)) : (null);
3984
- };
3985
-
3986
- tag$ = Imba.TAGS;
3987
- t$ = Imba.tag;
3988
- tc$ = Imba.tagWithFlags;
3989
- ti$ = Imba.tagWithId;
3990
- tic$ = Imba.tagWithIdAndFlags;
3991
- id$ = Imba.getTagSingleton;
3992
- return tag$wrap = Imba.getTagForDom;
3993
-
3994
-
3995
- })()
3996
- },{}]},{},[1])(1)
3997
- });