[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 /* 2 YUI 3.17.2 (build 9c3c78e) 3 Copyright 2014 Yahoo! Inc. All rights reserved. 4 Licensed under the BSD License. 5 http://yuilibrary.com/license/ 6 */ 7 8 YUI.add('event-synthetic', function (Y, NAME) { 9 10 /** 11 * Define new DOM events that can be subscribed to from Nodes. 12 * 13 * @module event 14 * @submodule event-synthetic 15 */ 16 var CustomEvent = Y.CustomEvent, 17 DOMMap = Y.Env.evt.dom_map, 18 toArray = Y.Array, 19 YLang = Y.Lang, 20 isObject = YLang.isObject, 21 isString = YLang.isString, 22 isArray = YLang.isArray, 23 query = Y.Selector.query, 24 noop = function () {}; 25 26 /** 27 * <p>The triggering mechanism used by SyntheticEvents.</p> 28 * 29 * <p>Implementers should not instantiate these directly. Use the Notifier 30 * provided to the event's implemented <code>on(node, sub, notifier)</code> or 31 * <code>delegate(node, sub, notifier, filter)</code> methods.</p> 32 * 33 * @class SyntheticEvent.Notifier 34 * @constructor 35 * @param handle {EventHandle} the detach handle for the subscription to an 36 * internal custom event used to execute the callback passed to 37 * on(..) or delegate(..) 38 * @param emitFacade {Boolean} take steps to ensure the first arg received by 39 * the subscription callback is an event facade 40 * @private 41 * @since 3.2.0 42 */ 43 function Notifier(handle, emitFacade) { 44 this.handle = handle; 45 this.emitFacade = emitFacade; 46 } 47 48 /** 49 * <p>Executes the subscription callback, passing the firing arguments as the 50 * first parameters to that callback. For events that are configured with 51 * emitFacade=true, it is common practice to pass the triggering DOMEventFacade 52 * as the first parameter. Barring a proper DOMEventFacade or EventFacade 53 * (from a CustomEvent), a new EventFacade will be generated. In that case, if 54 * fire() is called with a simple object, it will be mixed into the facade. 55 * Otherwise, the facade will be prepended to the callback parameters.</p> 56 * 57 * <p>For notifiers provided to delegate logic, the first argument should be an 58 * object with a "currentTarget" property to identify what object to 59 * default as 'this' in the callback. Typically this is gleaned from the 60 * DOMEventFacade or EventFacade, but if configured with emitFacade=false, an 61 * object must be provided. In that case, the object will be removed from the 62 * callback parameters.</p> 63 * 64 * <p>Additional arguments passed during event subscription will be 65 * automatically added after those passed to fire().</p> 66 * 67 * @method fire 68 * @param {EventFacade|DOMEventFacade|any} e (see description) 69 * @param {any[]} [arg*] additional arguments received by all subscriptions 70 * @private 71 */ 72 Notifier.prototype.fire = function (e) { 73 // first arg to delegate notifier should be an object with currentTarget 74 var args = toArray(arguments, 0, true), 75 handle = this.handle, 76 ce = handle.evt, 77 sub = handle.sub, 78 thisObj = sub.context, 79 delegate = sub.filter, 80 event = e || {}, 81 ret; 82 83 if (this.emitFacade) { 84 if (!e || !e.preventDefault) { 85 event = ce._getFacade(); 86 87 if (isObject(e) && !e.preventDefault) { 88 Y.mix(event, e, true); 89 args[0] = event; 90 } else { 91 args.unshift(event); 92 } 93 } 94 95 event.type = ce.type; 96 event.details = args.slice(); 97 98 if (delegate) { 99 event.container = ce.host; 100 } 101 } else if (delegate && isObject(e) && e.currentTarget) { 102 args.shift(); 103 } 104 105 sub.context = thisObj || event.currentTarget || ce.host; 106 ret = ce.fire.apply(ce, args); 107 108 // have to handle preventedFn and stoppedFn manually because 109 // Notifier CustomEvents are forced to emitFacade=false 110 if (e.prevented && ce.preventedFn) { 111 ce.preventedFn.apply(ce, args); 112 } 113 114 if (e.stopped && ce.stoppedFn) { 115 ce.stoppedFn.apply(ce, args); 116 } 117 118 sub.context = thisObj; // reset for future firing 119 120 // to capture callbacks that return false to stopPropagation. 121 // Useful for delegate implementations 122 return ret; 123 }; 124 125 /** 126 * Manager object for synthetic event subscriptions to aggregate multiple synths on the 127 * same node without colliding with actual DOM subscription entries in the global map of 128 * DOM subscriptions. Also facilitates proper cleanup on page unload. 129 * 130 * @class SynthRegistry 131 * @constructor 132 * @param el {HTMLElement} the DOM element 133 * @param yuid {String} the yuid stamp for the element 134 * @param key {String} the generated id token used to identify an event type + 135 * element in the global DOM subscription map. 136 * @private 137 */ 138 function SynthRegistry(el, yuid, key) { 139 this.handles = []; 140 this.el = el; 141 this.key = key; 142 this.domkey = yuid; 143 } 144 145 SynthRegistry.prototype = { 146 constructor: SynthRegistry, 147 148 // A few object properties to fake the CustomEvent interface for page 149 // unload cleanup. DON'T TOUCH! 150 type : '_synth', 151 fn : noop, 152 capture : false, 153 154 /** 155 * Adds a subscription from the Notifier registry. 156 * 157 * @method register 158 * @param handle {EventHandle} the subscription 159 * @since 3.4.0 160 */ 161 register: function (handle) { 162 handle.evt.registry = this; 163 this.handles.push(handle); 164 }, 165 166 /** 167 * Removes the subscription from the Notifier registry. 168 * 169 * @method _unregisterSub 170 * @param sub {Subscription} the subscription 171 * @since 3.4.0 172 */ 173 unregister: function (sub) { 174 var handles = this.handles, 175 events = DOMMap[this.domkey], 176 i; 177 178 for (i = handles.length - 1; i >= 0; --i) { 179 if (handles[i].sub === sub) { 180 handles.splice(i, 1); 181 break; 182 } 183 } 184 185 // Clean up left over objects when there are no more subscribers. 186 if (!handles.length) { 187 delete events[this.key]; 188 if (!Y.Object.size(events)) { 189 delete DOMMap[this.domkey]; 190 } 191 } 192 }, 193 194 /** 195 * Used by the event system's unload cleanup process. When navigating 196 * away from the page, the event system iterates the global map of element 197 * subscriptions and detaches everything using detachAll(). Normally, 198 * the map is populated with custom events, so this object needs to 199 * at least support the detachAll method to duck type its way to 200 * cleanliness. 201 * 202 * @method detachAll 203 * @private 204 * @since 3.4.0 205 */ 206 detachAll : function () { 207 var handles = this.handles, 208 i = handles.length; 209 210 while (--i >= 0) { 211 handles[i].detach(); 212 } 213 } 214 }; 215 216 /** 217 * <p>Wrapper class for the integration of new events into the YUI event 218 * infrastructure. Don't instantiate this object directly, use 219 * <code>Y.Event.define(type, config)</code>. See that method for details.</p> 220 * 221 * <p>Properties that MAY or SHOULD be specified in the configuration are noted 222 * below and in the description of <code>Y.Event.define</code>.</p> 223 * 224 * @class SyntheticEvent 225 * @constructor 226 * @param cfg {Object} Implementation pieces and configuration 227 * @since 3.1.0 228 * @in event-synthetic 229 */ 230 function SyntheticEvent() { 231 this._init.apply(this, arguments); 232 } 233 234 Y.mix(SyntheticEvent, { 235 Notifier: Notifier, 236 SynthRegistry: SynthRegistry, 237 238 /** 239 * Returns the array of subscription handles for a node for the given event 240 * type. Passing true as the third argument will create a registry entry 241 * in the event system's DOM map to host the array if one doesn't yet exist. 242 * 243 * @method getRegistry 244 * @param node {Node} the node 245 * @param type {String} the event 246 * @param create {Boolean} create a registration entry to host a new array 247 * if one doesn't exist. 248 * @return {Array} 249 * @static 250 * @protected 251 * @since 3.2.0 252 */ 253 getRegistry: function (node, type, create) { 254 var el = node._node, 255 yuid = Y.stamp(el), 256 key = 'event:' + yuid + type + '_synth', 257 events = DOMMap[yuid]; 258 259 if (create) { 260 if (!events) { 261 events = DOMMap[yuid] = {}; 262 } 263 if (!events[key]) { 264 events[key] = new SynthRegistry(el, yuid, key); 265 } 266 } 267 268 return (events && events[key]) || null; 269 }, 270 271 /** 272 * Alternate <code>_delete()</code> method for the CustomEvent object 273 * created to manage SyntheticEvent subscriptions. 274 * 275 * @method _deleteSub 276 * @param sub {Subscription} the subscription to clean up 277 * @private 278 * @since 3.2.0 279 */ 280 _deleteSub: function (sub) { 281 if (sub && sub.fn) { 282 var synth = this.eventDef, 283 method = (sub.filter) ? 'detachDelegate' : 'detach'; 284 285 this._subscribers = []; 286 287 if (CustomEvent.keepDeprecatedSubs) { 288 this.subscribers = {}; 289 } 290 291 synth[method](sub.node, sub, this.notifier, sub.filter); 292 this.registry.unregister(sub); 293 294 delete sub.fn; 295 delete sub.node; 296 delete sub.context; 297 } 298 }, 299 300 prototype: { 301 constructor: SyntheticEvent, 302 303 /** 304 * Construction logic for the event. 305 * 306 * @method _init 307 * @protected 308 */ 309 _init: function () { 310 var config = this.publishConfig || (this.publishConfig = {}); 311 312 // The notification mechanism handles facade creation 313 this.emitFacade = ('emitFacade' in config) ? 314 config.emitFacade : 315 true; 316 config.emitFacade = false; 317 }, 318 319 /** 320 * <p>Implementers MAY provide this method definition.</p> 321 * 322 * <p>Implement this function if the event supports a different 323 * subscription signature. This function is used by both 324 * <code>on()</code> and <code>delegate()</code>. The second parameter 325 * indicates that the event is being subscribed via 326 * <code>delegate()</code>.</p> 327 * 328 * <p>Implementations must remove extra arguments from the args list 329 * before returning. The required args for <code>on()</code> 330 * subscriptions are</p> 331 * <pre><code>[type, callback, target, context, argN...]</code></pre> 332 * 333 * <p>The required args for <code>delegate()</code> 334 * subscriptions are</p> 335 * 336 * <pre><code>[type, callback, target, filter, context, argN...]</code></pre> 337 * 338 * <p>The return value from this function will be stored on the 339 * subscription in the '_extra' property for reference elsewhere.</p> 340 * 341 * @method processArgs 342 * @param args {Array} parmeters passed to Y.on(..) or Y.delegate(..) 343 * @param delegate {Boolean} true if the subscription is from Y.delegate 344 * @return {any} 345 */ 346 processArgs: noop, 347 348 /** 349 * <p>Implementers MAY override this property.</p> 350 * 351 * <p>Whether to prevent multiple subscriptions to this event that are 352 * classified as being the same. By default, this means the subscribed 353 * callback is the same function. See the <code>subMatch</code> 354 * method. Setting this to true will impact performance for high volume 355 * events.</p> 356 * 357 * @property preventDups 358 * @type {Boolean} 359 * @default false 360 */ 361 //preventDups : false, 362 363 /** 364 * <p>Implementers SHOULD provide this method definition.</p> 365 * 366 * Implementation logic for subscriptions done via <code>node.on(type, 367 * fn)</code> or <code>Y.on(type, fn, target)</code>. This 368 * function should set up the monitor(s) that will eventually fire the 369 * event. Typically this involves subscribing to at least one DOM 370 * event. It is recommended to store detach handles from any DOM 371 * subscriptions to make for easy cleanup in the <code>detach</code> 372 * method. Typically these handles are added to the <code>sub</code> 373 * object. Also for SyntheticEvents that leverage a single DOM 374 * subscription under the hood, it is recommended to pass the DOM event 375 * object to <code>notifier.fire(e)</code>. (The event name on the 376 * object will be updated). 377 * 378 * @method on 379 * @param node {Node} the node the subscription is being applied to 380 * @param sub {Subscription} the object to track this subscription 381 * @param notifier {SyntheticEvent.Notifier} call notifier.fire(..) to 382 * trigger the execution of the subscribers 383 */ 384 on: noop, 385 386 /** 387 * <p>Implementers SHOULD provide this method definition.</p> 388 * 389 * <p>Implementation logic for detaching subscriptions done via 390 * <code>node.on(type, fn)</code>. This function should clean up any 391 * subscriptions made in the <code>on()</code> phase.</p> 392 * 393 * @method detach 394 * @param node {Node} the node the subscription was applied to 395 * @param sub {Subscription} the object tracking this subscription 396 * @param notifier {SyntheticEvent.Notifier} the Notifier used to 397 * trigger the execution of the subscribers 398 */ 399 detach: noop, 400 401 /** 402 * <p>Implementers SHOULD provide this method definition.</p> 403 * 404 * <p>Implementation logic for subscriptions done via 405 * <code>node.delegate(type, fn, filter)</code> or 406 * <code>Y.delegate(type, fn, container, filter)</code>. Like with 407 * <code>on()</code> above, this function should monitor the environment 408 * for the event being fired, and trigger subscription execution by 409 * calling <code>notifier.fire(e)</code>.</p> 410 * 411 * <p>This function receives a fourth argument, which is the filter 412 * used to identify which Node's are of interest to the subscription. 413 * The filter will be either a boolean function that accepts a target 414 * Node for each hierarchy level as the event bubbles, or a selector 415 * string. To translate selector strings into filter functions, use 416 * <code>Y.delegate.compileFilter(filter)</code>.</p> 417 * 418 * @method delegate 419 * @param node {Node} the node the subscription is being applied to 420 * @param sub {Subscription} the object to track this subscription 421 * @param notifier {SyntheticEvent.Notifier} call notifier.fire(..) to 422 * trigger the execution of the subscribers 423 * @param filter {String|Function} Selector string or function that 424 * accepts an event object and returns null, a Node, or an 425 * array of Nodes matching the criteria for processing. 426 * @since 3.2.0 427 */ 428 delegate : noop, 429 430 /** 431 * <p>Implementers SHOULD provide this method definition.</p> 432 * 433 * <p>Implementation logic for detaching subscriptions done via 434 * <code>node.delegate(type, fn, filter)</code> or 435 * <code>Y.delegate(type, fn, container, filter)</code>. This function 436 * should clean up any subscriptions made in the 437 * <code>delegate()</code> phase.</p> 438 * 439 * @method detachDelegate 440 * @param node {Node} the node the subscription was applied to 441 * @param sub {Subscription} the object tracking this subscription 442 * @param notifier {SyntheticEvent.Notifier} the Notifier used to 443 * trigger the execution of the subscribers 444 * @param filter {String|Function} Selector string or function that 445 * accepts an event object and returns null, a Node, or an 446 * array of Nodes matching the criteria for processing. 447 * @since 3.2.0 448 */ 449 detachDelegate : noop, 450 451 /** 452 * Sets up the boilerplate for detaching the event and facilitating the 453 * execution of subscriber callbacks. 454 * 455 * @method _on 456 * @param args {Array} array of arguments passed to 457 * <code>Y.on(...)</code> or <code>Y.delegate(...)</code> 458 * @param delegate {Boolean} true if called from 459 * <code>Y.delegate(...)</code> 460 * @return {EventHandle} the detach handle for this subscription 461 * @private 462 * since 3.2.0 463 */ 464 _on: function (args, delegate) { 465 var handles = [], 466 originalArgs = args.slice(), 467 extra = this.processArgs(args, delegate), 468 selector = args[2], 469 method = delegate ? 'delegate' : 'on', 470 nodes, handle; 471 472 // Can't just use Y.all because it doesn't support window (yet?) 473 nodes = (isString(selector)) ? 474 query(selector) : 475 toArray(selector || Y.one(Y.config.win)); 476 477 if (!nodes.length && isString(selector)) { 478 handle = Y.on('available', function () { 479 Y.mix(handle, Y[method].apply(Y, originalArgs), true); 480 }, selector); 481 482 return handle; 483 } 484 485 Y.Array.each(nodes, function (node) { 486 var subArgs = args.slice(), 487 filter; 488 489 node = Y.one(node); 490 491 if (node) { 492 if (delegate) { 493 filter = subArgs.splice(3, 1)[0]; 494 } 495 496 // (type, fn, el, thisObj, ...) => (fn, thisObj, ...) 497 subArgs.splice(0, 4, subArgs[1], subArgs[3]); 498 499 if (!this.preventDups || 500 !this.getSubs(node, args, null, true)) 501 { 502 handles.push(this._subscribe(node, method, subArgs, extra, filter)); 503 } 504 } 505 }, this); 506 507 return (handles.length === 1) ? 508 handles[0] : 509 new Y.EventHandle(handles); 510 }, 511 512 /** 513 * Creates a new Notifier object for use by this event's 514 * <code>on(...)</code> or <code>delegate(...)</code> implementation 515 * and register the custom event proxy in the DOM system for cleanup. 516 * 517 * @method _subscribe 518 * @param node {Node} the Node hosting the event 519 * @param method {String} "on" or "delegate" 520 * @param args {Array} the subscription arguments passed to either 521 * <code>Y.on(...)</code> or <code>Y.delegate(...)</code> 522 * after running through <code>processArgs(args)</code> to 523 * normalize the argument signature 524 * @param extra {any} Extra data parsed from 525 * <code>processArgs(args)</code> 526 * @param filter {String|Function} the selector string or function 527 * filter passed to <code>Y.delegate(...)</code> (not 528 * present when called from <code>Y.on(...)</code>) 529 * @return {EventHandle} 530 * @private 531 * @since 3.2.0 532 */ 533 _subscribe: function (node, method, args, extra, filter) { 534 var dispatcher = new Y.CustomEvent(this.type, this.publishConfig), 535 handle = dispatcher.on.apply(dispatcher, args), 536 notifier = new Notifier(handle, this.emitFacade), 537 registry = SyntheticEvent.getRegistry(node, this.type, true), 538 sub = handle.sub; 539 540 sub.node = node; 541 sub.filter = filter; 542 if (extra) { 543 this.applyArgExtras(extra, sub); 544 } 545 546 Y.mix(dispatcher, { 547 eventDef : this, 548 notifier : notifier, 549 host : node, // I forget what this is for 550 currentTarget: node, // for generating facades 551 target : node, // for generating facades 552 el : node._node, // For category detach 553 554 _delete : SyntheticEvent._deleteSub 555 }, true); 556 557 handle.notifier = notifier; 558 559 registry.register(handle); 560 561 // Call the implementation's "on" or "delegate" method 562 this[method](node, sub, notifier, filter); 563 564 return handle; 565 }, 566 567 /** 568 * <p>Implementers MAY provide this method definition.</p> 569 * 570 * <p>Implement this function if you want extra data extracted during 571 * processArgs to be propagated to subscriptions on a per-node basis. 572 * That is to say, if you call <code>Y.on('xyz', fn, xtra, 'div')</code> 573 * the data returned from processArgs will be shared 574 * across the subscription objects for all the divs. If you want each 575 * subscription to receive unique information, do that processing 576 * here.</p> 577 * 578 * <p>The default implementation adds the data extracted by processArgs 579 * to the subscription object as <code>sub._extra</code>.</p> 580 * 581 * @method applyArgExtras 582 * @param extra {any} Any extra data extracted from processArgs 583 * @param sub {Subscription} the individual subscription 584 */ 585 applyArgExtras: function (extra, sub) { 586 sub._extra = extra; 587 }, 588 589 /** 590 * Removes the subscription(s) from the internal subscription dispatch 591 * mechanism. See <code>SyntheticEvent._deleteSub</code>. 592 * 593 * @method _detach 594 * @param args {Array} The arguments passed to 595 * <code>node.detach(...)</code> 596 * @private 597 * @since 3.2.0 598 */ 599 _detach: function (args) { 600 // Can't use Y.all because it doesn't support window (yet?) 601 // TODO: Does Y.all support window now? 602 var target = args[2], 603 els = (isString(target)) ? 604 query(target) : toArray(target), 605 node, i, len, handles, j; 606 607 // (type, fn, el, context, filter?) => (type, fn, context, filter?) 608 args.splice(2, 1); 609 610 for (i = 0, len = els.length; i < len; ++i) { 611 node = Y.one(els[i]); 612 613 if (node) { 614 handles = this.getSubs(node, args); 615 616 if (handles) { 617 for (j = handles.length - 1; j >= 0; --j) { 618 handles[j].detach(); 619 } 620 } 621 } 622 } 623 }, 624 625 /** 626 * Returns the detach handles of subscriptions on a node that satisfy a 627 * search/filter function. By default, the filter used is the 628 * <code>subMatch</code> method. 629 * 630 * @method getSubs 631 * @param node {Node} the node hosting the event 632 * @param args {Array} the array of original subscription args passed 633 * to <code>Y.on(...)</code> (before 634 * <code>processArgs</code> 635 * @param filter {Function} function used to identify a subscription 636 * for inclusion in the returned array 637 * @param first {Boolean} stop after the first match (used to check for 638 * duplicate subscriptions) 639 * @return {EventHandle[]} detach handles for the matching subscriptions 640 */ 641 getSubs: function (node, args, filter, first) { 642 var registry = SyntheticEvent.getRegistry(node, this.type), 643 handles = [], 644 allHandles, i, len, handle; 645 646 if (registry) { 647 allHandles = registry.handles; 648 649 if (!filter) { 650 filter = this.subMatch; 651 } 652 653 for (i = 0, len = allHandles.length; i < len; ++i) { 654 handle = allHandles[i]; 655 if (filter.call(this, handle.sub, args)) { 656 if (first) { 657 return handle; 658 } else { 659 handles.push(allHandles[i]); 660 } 661 } 662 } 663 } 664 665 return handles.length && handles; 666 }, 667 668 /** 669 * <p>Implementers MAY override this to define what constitutes a 670 * "same" subscription. Override implementations should 671 * consider the lack of a comparator as a match, so calling 672 * <code>getSubs()</code> with no arguments will return all subs.</p> 673 * 674 * <p>Compares a set of subscription arguments against a Subscription 675 * object to determine if they match. The default implementation 676 * compares the callback function against the second argument passed to 677 * <code>Y.on(...)</code> or <code>node.detach(...)</code> etc.</p> 678 * 679 * @method subMatch 680 * @param sub {Subscription} the existing subscription 681 * @param args {Array} the calling arguments passed to 682 * <code>Y.on(...)</code> etc. 683 * @return {Boolean} true if the sub can be described by the args 684 * present 685 * @since 3.2.0 686 */ 687 subMatch: function (sub, args) { 688 // Default detach cares only about the callback matching 689 return !args[1] || sub.fn === args[1]; 690 } 691 } 692 }, true); 693 694 Y.SyntheticEvent = SyntheticEvent; 695 696 /** 697 * <p>Defines a new event in the DOM event system. Implementers are 698 * responsible for monitoring for a scenario whereby the event is fired. A 699 * notifier object is provided to the functions identified below. When the 700 * criteria defining the event are met, call notifier.fire( [args] ); to 701 * execute event subscribers.</p> 702 * 703 * <p>The first parameter is the name of the event. The second parameter is a 704 * configuration object which define the behavior of the event system when the 705 * new event is subscribed to or detached from. The methods that should be 706 * defined in this configuration object are <code>on</code>, 707 * <code>detach</code>, <code>delegate</code>, and <code>detachDelegate</code>. 708 * You are free to define any other methods or properties needed to define your 709 * event. Be aware, however, that since the object is used to subclass 710 * SyntheticEvent, you should avoid method names used by SyntheticEvent unless 711 * your intention is to override the default behavior.</p> 712 * 713 * <p>This is a list of properties and methods that you can or should specify 714 * in the configuration object:</p> 715 * 716 * <dl> 717 * <dt><code>on</code></dt> 718 * <dd><code>function (node, subscription, notifier)</code> The 719 * implementation logic for subscription. Any special setup you need to 720 * do to create the environment for the event being fired--E.g. native 721 * DOM event subscriptions. Store subscription related objects and 722 * state on the <code>subscription</code> object. When the 723 * criteria have been met to fire the synthetic event, call 724 * <code>notifier.fire(e)</code>. See Notifier's <code>fire()</code> 725 * method for details about what to pass as parameters.</dd> 726 * 727 * <dt><code>detach</code></dt> 728 * <dd><code>function (node, subscription, notifier)</code> The 729 * implementation logic for cleaning up a detached subscription. E.g. 730 * detach any DOM subscriptions added in <code>on</code>.</dd> 731 * 732 * <dt><code>delegate</code></dt> 733 * <dd><code>function (node, subscription, notifier, filter)</code> The 734 * implementation logic for subscription via <code>Y.delegate</code> or 735 * <code>node.delegate</code>. The filter is typically either a selector 736 * string or a function. You can use 737 * <code>Y.delegate.compileFilter(selectorString)</code> to create a 738 * filter function from a selector string if needed. The filter function 739 * expects an event object as input and should output either null, a 740 * matching Node, or an array of matching Nodes. Otherwise, this acts 741 * like <code>on</code> DOM event subscriptions. Store subscription 742 * related objects and information on the <code>subscription</code> 743 * object. When the criteria have been met to fire the synthetic event, 744 * call <code>notifier.fire(e)</code> as noted above.</dd> 745 * 746 * <dt><code>detachDelegate</code></dt> 747 * <dd><code>function (node, subscription, notifier)</code> The 748 * implementation logic for cleaning up a detached delegate subscription. 749 * E.g. detach any DOM delegate subscriptions added in 750 * <code>delegate</code>.</dd> 751 * 752 * <dt><code>publishConfig</code></dt> 753 * <dd>(Object) The configuration object that will be used to instantiate 754 * the underlying CustomEvent. See Notifier's <code>fire</code> method 755 * for details.</dd> 756 * 757 * <dt><code>processArgs</code></dt 758 * <dd> 759 * <p><code>function (argArray, fromDelegate)</code> Optional method 760 * to extract any additional arguments from the subscription 761 * signature. Using this allows <code>on</code> or 762 * <code>delegate</code> signatures like 763 * <code>node.on("hover", overCallback, 764 * outCallback)</code>.</p> 765 * <p>When processing an atypical argument signature, make sure the 766 * args array is returned to the normal signature before returning 767 * from the function. For example, in the "hover" example 768 * above, the <code>outCallback</code> needs to be <code>splice</code>d 769 * out of the array. The expected signature of the args array for 770 * <code>on()</code> subscriptions is:</p> 771 * <pre> 772 * <code>[type, callback, target, contextOverride, argN...]</code> 773 * </pre> 774 * <p>And for <code>delegate()</code>:</p> 775 * <pre> 776 * <code>[type, callback, target, filter, contextOverride, argN...]</code> 777 * </pre> 778 * <p>where <code>target</code> is the node the event is being 779 * subscribed for. You can see these signatures documented for 780 * <code>Y.on()</code> and <code>Y.delegate()</code> respectively.</p> 781 * <p>Whatever gets returned from the function will be stored on the 782 * <code>subscription</code> object under 783 * <code>subscription._extra</code>.</p></dd> 784 * <dt><code>subMatch</code></dt> 785 * <dd> 786 * <p><code>function (sub, args)</code> Compares a set of 787 * subscription arguments against a Subscription object to determine 788 * if they match. The default implementation compares the callback 789 * function against the second argument passed to 790 * <code>Y.on(...)</code> or <code>node.detach(...)</code> etc.</p> 791 * </dd> 792 * </dl> 793 * 794 * @method define 795 * @param type {String} the name of the event 796 * @param config {Object} the prototype definition for the new event (see above) 797 * @param force {Boolean} override an existing event (use with caution) 798 * @return {SyntheticEvent} the subclass implementation instance created to 799 * handle event subscriptions of this type 800 * @static 801 * @for Event 802 * @since 3.1.0 803 * @in event-synthetic 804 */ 805 Y.Event.define = function (type, config, force) { 806 var eventDef, Impl, synth; 807 808 if (type && type.type) { 809 eventDef = type; 810 force = config; 811 } else if (config) { 812 eventDef = Y.merge({ type: type }, config); 813 } 814 815 if (eventDef) { 816 if (force || !Y.Node.DOM_EVENTS[eventDef.type]) { 817 Impl = function () { 818 SyntheticEvent.apply(this, arguments); 819 }; 820 Y.extend(Impl, SyntheticEvent, eventDef); 821 synth = new Impl(); 822 823 type = synth.type; 824 825 Y.Node.DOM_EVENTS[type] = Y.Env.evt.plugins[type] = { 826 eventDef: synth, 827 828 on: function () { 829 return synth._on(toArray(arguments)); 830 }, 831 832 delegate: function () { 833 return synth._on(toArray(arguments), true); 834 }, 835 836 detach: function () { 837 return synth._detach(toArray(arguments)); 838 } 839 }; 840 841 } 842 } else if (isString(type) || isArray(type)) { 843 Y.Array.each(toArray(type), function (t) { 844 Y.Node.DOM_EVENTS[t] = 1; 845 }); 846 } 847 848 return synth; 849 }; 850 851 852 }, '3.17.2', {"requires": ["node-base", "event-custom-complex"]});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |