1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
4
<title>YUI3 Custom Event Tests</title>
5
<script type="text/javascript" src="../../../build/yui/yui.js"></script>
8
<body class="yui3-skin-sam">
10
<p><input type="button" value="Run Tests" id="btnRun" disabled="true" /></p>
11
<div id="adiv">a div</div>
12
<div id="demo" class="yui-module">
14
<h4>Animation Demo</h4>
15
<a title="remove module" class="yui-remove"><em>x</em></a>
19
<p>This an example of what you can do with the YUI Animation Utility.</p>
20
<p><em>Follow the instructions above to see the animation in action.</em></p>
26
<script type="text/javascript">
32
//YUI.add("selector-native", function(){});
34
filter: (window.location.search.match(/[?&]filter=([^&]+)/) || [])[1] || 'min',
37
Y.log('CSS is done loading', 'info', 'testcase');
39
logExclude: { get: true, Dom: true, Selector: true, Node: true, attribute: true, event: true, base: true, widget: true },
46
}).use("dump", "test", "anim", "console", function(Y) {
48
// Y.Global.on('yui:log', function(e) {
49
// console.log('GLOBAL LOG: ' + e.msg);
52
var button = Y.one('#btnRun');
55
button.set("disabled", false);
56
Y.on("click", function() {
60
var myConsole = new Y.Console().render();
63
var testEventTarget = new Y.Test.Case({
64
name: "Custom event tests",
68
testStopFnOnceFromBubbleTarget: "ticket pending",
69
testStopFnFromBubbleTarget: "ticket pending"
73
testAugment: function() {
77
var O = function(id) {
79
Y.log('O constructor executed ' + id);
88
// pass configuration info into EventTarget with the following
90
Y.augment(O, Y.EventTarget, null, null, {
95
handle = o.on('testAugment', function(e, arg1, arg2) {
96
Y.Assert.isTrue(this instanceof O);
97
Y.Assert.isTrue(e instanceof Y.EventFacade);
98
Y.Assert.isTrue(e.foo === 'afoo');
99
Y.Assert.isTrue(e.details[1] === 1);
100
Y.Assert.isTrue(arg1 === 1);
101
Y.Assert.isTrue(arg2 === 2);
105
o.fire('testAugment', { foo: 'afoo' }, 1, 2);
107
Y.Assert.isTrue(fired);
111
// if the first argument is not an object, the
112
// event facade is moved in front of the args rather
113
// than overwriting existing object.
114
o.on('testAugment', function(e, arg1, arg2) {
115
Y.Assert.areEqual(1, arg1);
116
Y.Assert.areEqual(2, arg2);
119
o.fire('testAugment', 1, 2);
123
test_detach_by_signature: function() {
125
var anim = new Y.Anim({
130
tester = function() {
132
Y.detach('foo', tester);
139
Y.Assert.areEqual(1, count);
141
var onEnd = function() {
143
// this.detach('anim:end', onEnd);
144
this.detach('end', onEnd);
147
easing: Y.Easing.bounceOut
152
throw new Error('onEnd should only have happened once');
156
// anim.on('end', onEnd);
164
testExtend: function() {
168
var Base = function() {
169
Y.log('Base constructor executed');
170
arguments.callee.superclass.constructor.apply(this, arguments);
173
Y.extend(Base, Y.EventTarget, {
175
Y.log('all your base...');
180
b.on('testExtend', function(arg1, arg2) {
181
Y.Assert.isTrue(this instanceof Base);
182
Y.Assert.isTrue(arg1 === 1);
183
Y.Assert.isTrue(arg2 === 2);
187
b.fire('testExtend', 1, 2);
189
Y.Assert.isTrue(fired);
192
testPrefix: function() {
197
var O = function(id) {
199
Y.log('O constructor executed ' + id);
208
// pass configuration info into EventTarget with the following
210
Y.augment(O, Y.EventTarget, null, null, {
216
o.on('testPrefix', function(e, arg1, arg2) {
217
Y.Assert.isTrue(this instanceof O);
221
o.on('prefix:testPrefix', function(e, arg1, arg2) {
222
Y.Assert.isTrue(this instanceof O);
226
o.fire('testPrefix', { foo: 'afoo' }, 1, 2);
228
Y.Assert.isTrue(fired1);
229
// Y.Assert.isTrue(fired2);
234
o.fire('prefix:testPrefix', { foo: 'afoo' }, 1, 2);
235
Y.Assert.isTrue(fired1);
236
Y.Assert.isTrue(fired2);
239
testDetachKey: function() {
244
Y.on('handle|test:event', function() {
249
Y.fire('test:event');
250
Y.Assert.isTrue(fired1);
251
Y.Assert.isFalse(fired2);
253
Y.detach('handle|test:event');
258
Y.on('handle|test:event', function() {
262
// first lisener detached, added a new listener
263
Y.fire('test:event');
264
Y.Assert.isFalse(fired1);
265
Y.Assert.isTrue(fired2);
267
Y.detach('handle|test:event');
271
Y.after('handle|test:event', function(arg1) {
272
Y.Assert.areEqual('orange', arg1);
273
Y.Assert.isTrue(fired1);
278
Y.on('handle|test:event', function(arg1) {
279
Y.Assert.areEqual('orange', arg1);
280
Y.Assert.isFalse(fired2);
284
// testing on and after order
285
Y.fire('test:event', 'orange');
290
// spaces after the comma or lack thereof should have
291
// no effect on the addition or removal of listeners
292
var ret = Y.detach('handle|test:event');
294
Y.Assert.areEqual(Y, ret);
296
// added both an on listener and an after listener,
297
// then detached both
298
Y.fire('test:event', 'orange');
299
Y.Assert.isFalse(fired1);
300
Y.Assert.isFalse(fired2);
304
testDetachAllByKey: function() {
309
Y.after('handle|event2', function() {
313
Y.on('handle|event2', function() {
318
Y.detach('handle|*');
322
Y.Assert.isFalse(fired1, 'fired1, the after listener should not have fired.');
323
Y.Assert.isFalse(fired2, 'fired2, the on listener should not have fired.');
327
testChain: function() {
335
// should be executed once, after f2
336
var f1 = function() {
337
Y.Assert.isTrue(fired2);
341
// should be executed once, before f1
342
var f2 = function() {
343
Y.Assert.isFalse(fired1);
347
// should be executed once, different event from f1 and f2
348
var f3 = function() {
352
// detached before fired, should not executed
353
var f4 = function() {
357
// should fire once, preserving the custom prefix rather
358
// than using the configured event target prefix
359
var f5 = function() {
363
// configure chaining via global default or on the event target
364
YUI({ /* chain: true */
365
base:'../../../build/',
369
}).use('event-custom', function(Y2) {
371
var o = new Y2.EventTarget({
376
// without event target prefix manipulation (incomplete now)
377
// @TODO an error here is throwing an uncaught exception rather than failing the test
378
// Y2.after('p:e', f1).on('p:e', f2).on('p:e2', f3).on('detach, p:e', f4).detach('detach, p:e').fire('p:e').fire('p:e2');
380
// with event target prefix manipulation ('e' is the same event as 'foo:e',
381
// but 'pre:e' is a different event only accessible by using that exact name)
382
o.after('e', f1).on('foo:e', f2).on('foo:e2', f3).on('detach, e', f4).detach('detach,e').fire('foo:e').fire('e2').on('pre:e', f5).fire('pre:e');
384
Y.Assert.isTrue(fired1); // verifies chaining, on/after order, and adding the event target prefix
385
Y.Assert.isTrue(fired2); // verifies chaining, on/after order, and accepting the prefix in the event name
386
Y.Assert.isTrue(fired3); // verifies no interaction between events, and prefix manipulation
387
Y.Assert.isFalse(fired4); // verifies detach works (regardless of spaces after comma)
388
Y.Assert.isTrue(fired5); // verifies custom prefix
394
testObjType: function() {
397
'y:click': function() {f1 = true},
398
'y:clack': function() {f2 = true}
408
testBubble: function() {
415
a = new Y.EventTarget(config),
416
b = new Y.EventTarget(config);
420
// this should not be necessary // fixed
421
// b.publish('test:foo');
423
a.on('test:foo', function(e) {
425
// we will fire this on the parent, so that should be the target
426
Y.Assert.areEqual(b, e.target);
427
Y.Assert.areEqual(a, e.currentTarget);
430
ret = b.fire('test:foo', {}, b);
432
Y.Assert.areEqual(1, count);
433
Y.Assert.isTrue(ret);
435
b.on('test:foo', function(e) {
439
ret = b.fire('test:foo', {}, b);
441
Y.Assert.areEqual(1, count);
442
Y.Assert.isFalse(ret);
446
testPreventFnOnce: function() {
448
Y.publish('y:foo1', {
450
preventedFn: function() {
452
Y.Assert.isTrue(this instanceof YUI);
456
Y.on('y:foo1', function(e) {
460
Y.on('y:foo1', function(e) {
466
Y.Assert.areEqual(1, count);
469
testPreventFromBubbleTarget: function () {
471
target = new Y.EventTarget({ prefix: 'x' });
473
target.publish('foo', {
475
preventedFn: function() {
482
Y.on('x:foo', function(e) {
488
Y.Assert.areEqual(1, count);
491
testPreventedFnOnceFromBubbleTarget: function () {
493
target = new Y.EventTarget({ prefix: 'x' });
495
target.publish('foo', {
497
preventedFn: function() {
504
Y.on('x:foo', function(e) {
508
Y.on('x:foo', function(e) {
514
Y.Assert.areEqual(1, count);
516
target.on('foo', function (e) {
522
Y.Assert.areEqual(2, count);
525
testStopFnOnce: function () {
527
target = new Y.EventTarget({ prefix: 'a' });
529
target.publish('foo', {
531
stoppedFn: function () {
536
target.on('foo', function (e) {
540
target.on('foo', function (e) {
546
Y.Assert.areEqual(1, count);
549
testStopFnFromBubbleTarget: function () {
551
origin = new Y.EventTarget({ prefix: 'a' }),
552
targetB = new Y.EventTarget({ prefix: 'b' });
554
origin.publish('foo', {
556
stoppedFn: function () {
561
targetB.on('foo', function (e) {
567
Y.Assert.areEqual(1, count);
570
testStopFnOnceFromBubbleTarget: function () {
572
origin = new Y.EventTarget({ prefix: 'a' }),
573
targetB = new Y.EventTarget({ prefix: 'b' }),
574
targetC = new Y.EventTarget({ prefix: 'c' });
576
origin.publish('foo', {
578
stoppedFn: function() {
583
targetB.addTarget(targetC);
584
origin.addTarget(targetB);
586
targetB.on('foo', function (e) {
590
targetB.on('foo', function (e) {
596
Y.Assert.areEqual(1, count, "stopProp called twice from bubble target resulted in stoppedFn called wrong number of times");
600
targetC.on('foo', function (e) {
606
Y.Assert.areEqual(1, count, "stopProp called from intermediate bubble target didn't prevent stoppedFn call from subsequent bubble target");
610
origin.on('foo', function (e) {
616
Y.Assert.areEqual(1, count, "stopProp called from event origin subscription didn't prevent calls to stoppedFn from bubble target");
619
testDetachHandle: function() {
620
var count = 0, handle, handle2;
625
Y.on('y:foo', function(e) {
630
handle = Y.on('y:foo', function(e) {
634
handle2 = Y.on('y:foo', function(e) {
642
Y.Assert.areEqual(1, count);
646
var handle3 = Y.on('y:click', function() {
654
var o = new Y.EventTarget();
658
o.on('foo', function(e) {
662
o.on('foo', function(e) {
670
Y.Assert.areEqual(0, count);
672
var handle3 = Y.on('y:click', function() {
676
// detachAll can't be allowed to work on the YUI instance.
681
Y.Assert.areEqual(1, count);
684
testBroadcast: function() {
685
var o = new Y.EventTarget(), s1, s2, s3, s4;
687
o.publish('y:foo2', {
692
Y.on('y:foo2', function() {
693
Y.log('Y foo2 executed');
697
Y.Global.on('y:foo2', function() {
698
Y.log('GLOBAL foo2 executed');
704
Y.Assert.areEqual(1, s1);
705
Y.Assert.areNotEqual(1, s2);
715
Y.on('y:bar', function() {
716
Y.log('Y bar executed');
720
Y.Global.on('y:bar', function() {
721
Y.log('GLOBAL bar executed');
727
Y.Assert.areEqual(1, s3);
728
Y.Assert.areEqual(1, s4);
730
Y.Global.on('y:bar', function(e) {
731
Y.Assert.areEqual(0, e.stopped);
732
// Y.Assert.areEqual(0, e._event.stopped);
733
Y.log('GLOBAL bar executed');
740
Y.Global.detachAll();
744
test_fire_once: function() {
748
Y.publish('fireonce', {
752
Y.fire('fireonce', 'foo', 'bar');
754
Y.on('fireonce', function(arg1, arg2) {
756
Y.Assert.areEqual('foo', arg1, 'arg1 not correct for lazy fireOnce listener')
757
Y.Assert.areEqual('bar', arg2, 'arg2 not correct for lazy fireOnce listener')
760
Y.fire('fireonce', 'foo2', 'bar2');
761
Y.fire('fireonce', 'foo3', 'bar3');
763
global_notified = false;
765
Y.on('fireonce', function(arg1, arg2) {
766
Y.log('the notification is asynchronous, so I need to wait for this test');
767
Y.Assert.areEqual(1, notified, 'listener notified more than once.');
768
global_notified = true;
771
// it is no longer asynchronous
772
// Y.Assert.isFalse(global_notified, 'notification was not asynchronous');
776
test_async_fireonce: function() {
777
Y.Assert.isTrue(global_notified, 'asynchronous notification did not seem to work.');
780
test_node_publish: function() {
781
var node = Y.one('#adiv');
783
var preventCount = 0, heard = 0;
784
node.publish('foo1', {
786
// should only be called once
787
preventedFn: function() {
789
Y.Assert.isTrue(this instanceof Y.Node);
793
node.on('foo1', function(e) {
794
Y.Assert.areEqual('faking foo', e.type);
795
Y.Assert.areEqual('foo1', e._type);
800
node.on('foo1', function(e) {
809
Y.Assert.areEqual(1, preventCount);
810
Y.Assert.areEqual(2, heard);
815
// BUBBLE, DEFAULT BEHAVIOR
817
// SRC, DEFAULT BEHAVIOR
819
__testBubbleSequence300GA: function() {
829
leaf = new Y.EventTarget(config),
830
branch = new Y.EventTarget(config),
831
root = new Y.EventTarget(config);
834
branch.name = 'branch';
837
leaf.addTarget(branch);
838
branch.addTarget(root);
840
leaf.publish('test:foo', { defaultFn: fn});
841
branch.publish('test:foo', { defaultFn: fn});
842
root.publish('test:foo', { defaultFn: fn});
844
leaf.on('test:foo', function(e) {
845
Y.Assert.areEqual(0, count, 'leaf.on should be first');
846
Y.Assert.isNull(called, 'leaf.on should be executed before any default function');
850
branch.on('test:foo', function() {
851
Y.Assert.areEqual(1, count, 'branch.on should be second');
852
Y.Assert.isNull(called, 'branch.on should be executed before any default function');
856
root.on('test:foo', function() {
857
Y.Assert.areEqual(2, count, 'root.on should be third');
858
Y.Assert.isNull(called, 'root.on should be executed before any default function');
862
root.after('test:foo', function() {
863
Y.Assert.areEqual(3, count, 'root.after should be fourth');
864
Y.Assert.areEqual('root', called, 'root.after should be executed after the root default function');
868
branch.after('test:foo', function() {
869
Y.Assert.areEqual(4, count, 'branch.after should be fifth');
870
Y.Assert.areEqual('branch', called, 'branch.after should be executed after the branch default function');
874
leaf.after('test:foo', function(e) {
875
Y.Assert.areEqual(5, count, 'leaf.after should be sixth and last');
876
Y.Assert.areEqual('leaf', called, 'leaf.after should be executed after the leaf default function');
880
leaf.fire('test:foo', {}, leaf);
881
Y.Assert.areEqual(6, count);
885
// Ideally it should be this, but the defaultFn order is the least important bit
886
// and there are issues changing the order.
889
// SRC, DEFAULT BEHAVIOR
890
// BUBBLE, DEFAULT BEHAVIOR (unless configured to only execute the default function on the target)
894
// The actual order is this:
897
// BUBBLE, DEFAULT BEHAVIOR
898
// SRC, DEFAULT BEHAVIOR (unless configured to only execute the default function on the target)
901
testAlternativeSequencePost300GA: function() {
911
leaf = new Y.EventTarget(config),
912
branch = new Y.EventTarget(config),
913
root = new Y.EventTarget(config);
916
branch.name = 'branch';
919
leaf.addTarget(branch);
920
branch.addTarget(root);
922
leaf.publish('test:foo', { defaultFn: fn});
923
branch.publish('test:foo', { defaultFn: fn});
924
root.publish('test:foo', { defaultFn: fn});
926
leaf.on('test:foo', function(e) {
927
Y.Assert.areEqual(0, count, 'leaf.on should be first');
928
Y.Assert.isNull(called, 'leaf.on should be executed before any default function');
932
branch.on('test:foo', function() {
933
Y.Assert.areEqual(1, count, 'branch.on should be second');
934
Y.Assert.isNull(called, 'branch.on should be executed before any default function');
938
root.on('test:foo', function() {
939
Y.Assert.areEqual(2, count, 'root.on should be third');
940
Y.Assert.isNull(called, 'root.on should be executed before any default function');
944
leaf.after('test:foo', function(e) {
945
Y.Assert.areEqual(3, count, 'leaf.after should be fourth');
946
// Y.Assert.areEqual('root', called, 'leaf.after should be executed after the root default function');
947
Y.Assert.areEqual('leaf', called, 'leaf.after should be executed after the root default function');
951
branch.after('test:foo', function() {
952
Y.Assert.areEqual(4, count, 'branch.after should be fifth');
953
// Y.Assert.areEqual('root', called, 'leaf.after should be executed after the root default function');
954
Y.Assert.areEqual('leaf', called, 'leaf.after should be executed after the root default function');
958
root.after('test:foo', function() {
959
Y.Assert.areEqual(5, count, 'root.after should be sixth and last');
960
// Y.Assert.areEqual('root', called, 'leaf.after should be executed after the root default function');
961
Y.Assert.areEqual('leaf', called, 'leaf.after should be executed after the root default function');
965
leaf.fire('test:foo', {}, leaf);
966
Y.Assert.areEqual(6, count, 'total subscriber count');
970
testStarSubscriber: function() {
978
z = new Y.EventTarget(config),
979
a = new Y.EventTarget(config),
980
b = new Y.EventTarget(config);
985
z.on('*:foo', function(e) {
987
// b -> a -> z -- the parent's parent should be the target
988
Y.Assert.areEqual(b, e.target);
989
Y.Assert.areEqual(z, e.currentTarget);
992
Y.Assert.areEqual('a:foo', e.type);
995
Y.Assert.areEqual('b:foo', e.type);
998
Y.Assert.areEqual('stars:foo', e.type);
1003
ret = b.fire('a:foo', {}, b);
1005
Y.Assert.areEqual(1, count);
1006
Y.Assert.isTrue(ret);
1008
ret = b.fire('b:foo', {}, b);
1010
Y.Assert.areEqual(2, count);
1011
Y.Assert.isTrue(ret);
1013
// if the event target is not configured with a prefix, this won't work by design.
1014
ret = b.fire('foo', {}, b);
1015
Y.Assert.areEqual(3, count);
1017
Y.Assert.isTrue(ret);
1020
testPreventBubble: function() {
1028
z = new Y.EventTarget(config),
1029
a = new Y.EventTarget(config),
1030
b = new Y.EventTarget(config);
1035
z.after('*:foo', function(e) {
1037
// e.preventDefault();
1038
Y.Assert.areEqual(b, e.target);
1042
ret = b.fire('a:foo', {}, b);
1044
Y.Assert.areEqual(0, count);
1047
test_listen_once: function() {
1051
Y.once(['foo', 'bar'], function(e) {
1055
Y.fire('foo', 'bar');
1056
Y.fire('bar', 'bar');
1058
Y.Assert.areEqual(2, count);
1060
Y.fire('foo', 'bar');
1061
Y.fire('bar', 'bar');
1063
Y.Assert.areEqual(2, count);
1067
test_array_type_param: function() {
1070
var handle1 = Y.after(['foo', 'bar'], function(type) {
1071
result += 'after' + type;
1074
var handle2 = Y.on(['foo', 'bar'], function(type) {
1075
result += 'on' + type;
1078
Y.fire('foo', 'foo');
1079
Y.fire('bar', 'bar');
1081
Y.Assert.areEqual('onfooafterfooonbarafterbar', result);
1086
Y.fire('foo', 'foo');
1087
Y.fire('bar', 'bar');
1089
Y.Assert.areEqual('onfooafterfooonbarafterbar', result);
1092
test_bubble_config: function() {
1094
var a = new Y.EventTarget(),
1095
b = new Y.EventTarget(),
1103
b.on("foo", function(e) {
1104
result = (e instanceof Y.EventFacade);
1109
Y.Assert.isTrue(result);
1113
test_onceAfter: function () {
1114
var a = new Y.EventTarget({ emitFacade: true, prefix: 'a' }),
1117
a.on('foo', function () { result += 'A'; });
1118
a.once('foo', function () { result += 'B'; });
1119
a.after('foo', function () { result += 'C'; });
1120
a.onceAfter('foo', function () { result += 'D'; });
1125
Y.Assert.areSame("ABCDAC", result);
1128
test_multiple_object_publish: function () {
1129
var target = new Y.EventTarget({ emitFacade: true, prefix: 'a' }),
1132
target.publish({ foo: {} });
1135
defaultFn: function () { pass = true; }
1141
Y.Assert.isTrue(pass);
1145
Y.Test.Runner.setName("CustomEvent");
1146
Y.Test.Runner.add(testEventTarget);
1147
Y.Test.Runner.run();
1151
// base: "../../../build/",
1154
// useConsole: true,
1155
// logExclude: {Dom: true, Selector: true, Node: true, attribute: true, base: true, loader: true, get: true, widget: true}
1156
// }).use("datasource", function(Y) {
1157
// Y.log('loaded datasource: ' + Y.DataSource);