Dashboard sipadu mbip
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

event-focus.js 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. Copyright (c) 2010, Yahoo! Inc. All rights reserved.
  3. Code licensed under the BSD License:
  4. http://developer.yahoo.com/yui/license.html
  5. version: 3.4.0
  6. build: nightly
  7. */
  8. YUI.add('event-focus', function(Y) {
  9. /**
  10. * Adds bubbling and delegation support To DoM events focus and blur.
  11. *
  12. * @module event
  13. * @submodule event-focus
  14. */
  15. var Event = Y.Event,
  16. YLang = Y.Lang,
  17. isString = YLang.isString,
  18. useActivate = YLang.isFunction(
  19. Y.DOM.create('<p onbeforeactivate=";"/>').onbeforeactivate);
  20. function define(type, proxy, directEvent) {
  21. var nodeDataKey = '_' + type + 'Notifiers';
  22. Y.Event.define(type, {
  23. _attach: function (el, notifier, delegate) {
  24. if (Y.DOM.isWindow(el)) {
  25. return Event._attach([type, function (e) {
  26. notifier.fire(e);
  27. }, el]);
  28. } else {
  29. return Event._attach(
  30. [proxy, this._proxy, el, this, notifier, delegate],
  31. { capture: true });
  32. }
  33. },
  34. _proxy: function (e, notifier, delegate) {
  35. var node = e.target,
  36. notifiers = node.getData(nodeDataKey),
  37. yuid = Y.stamp(e.currentTarget._node),
  38. defer = (useActivate || e.target !== e.currentTarget),
  39. sub = notifier.handle.sub,
  40. filterArgs = [node, e].concat(sub.args || []),
  41. directSub;
  42. notifier.currentTarget = (delegate) ? node : e.currentTarget;
  43. notifier.container = (delegate) ? e.currentTarget : null;
  44. if (!sub.filter || sub.filter.apply(node, filterArgs)) {
  45. // Maintain a list to handle subscriptions from nested
  46. // containers div#a>div#b>input #a.on(focus..) #b.on(focus..),
  47. // use one focus or blur subscription that fires notifiers from
  48. // #b then #a to emulate bubble sequence.
  49. if (!notifiers) {
  50. notifiers = {};
  51. node.setData(nodeDataKey, notifiers);
  52. // only subscribe to the element's focus if the target is
  53. // not the current target (
  54. if (defer) {
  55. directSub = Event._attach(
  56. [directEvent, this._notify, node._node]).sub;
  57. directSub.once = true;
  58. }
  59. }
  60. if (!notifiers[yuid]) {
  61. notifiers[yuid] = [];
  62. }
  63. notifiers[yuid].push(notifier);
  64. if (!defer) {
  65. this._notify(e);
  66. }
  67. }
  68. },
  69. _notify: function (e, container) {
  70. var node = e.currentTarget,
  71. notifiers = node.getData(nodeDataKey),
  72. // document.get('ownerDocument') returns null
  73. doc = node.get('ownerDocument') || node,
  74. target = node,
  75. nots = [],
  76. notifier, i, len;
  77. if (notifiers) {
  78. // Walk up the parent axis until the origin node,
  79. while (target && target !== doc) {
  80. nots.push.apply(nots, notifiers[Y.stamp(target)] || []);
  81. target = target.get('parentNode');
  82. }
  83. nots.push.apply(nots, notifiers[Y.stamp(doc)] || []);
  84. for (i = 0, len = nots.length; i < len; ++i) {
  85. notifier = nots[i];
  86. e.currentTarget = nots[i].currentTarget;
  87. if (notifier.container) {
  88. e.container = notifier.container;
  89. }
  90. notifier.fire(e);
  91. }
  92. // clear the notifications list (mainly for delegation)
  93. node.clearData(nodeDataKey);
  94. }
  95. },
  96. on: function (node, sub, notifier) {
  97. sub.onHandle = this._attach(node._node, notifier);
  98. },
  99. detach: function (node, sub) {
  100. sub.onHandle.detach();
  101. },
  102. delegate: function (node, sub, notifier, filter) {
  103. if (isString(filter)) {
  104. sub.filter = Y.delegate.compileFilter(filter);
  105. }
  106. sub.delegateHandle = this._attach(node._node, notifier, true);
  107. },
  108. detachDelegate: function (node, sub) {
  109. sub.delegateHandle.detach();
  110. }
  111. }, true);
  112. }
  113. // For IE, we need to defer to focusin rather than focus because
  114. // `el.focus(); doSomething();` executes el.onbeforeactivate, el.onactivate,
  115. // el.onfocusin, doSomething, then el.onfocus. All others support capture
  116. // phase focus, which executes before doSomething. To guarantee consistent
  117. // behavior for this use case, IE's direct subscriptions are made against
  118. // focusin so subscribers will be notified before js following el.focus() is
  119. // executed.
  120. if (useActivate) {
  121. // name capture phase direct subscription
  122. define("focus", "beforeactivate", "focusin");
  123. define("blur", "beforedeactivate", "focusout");
  124. } else {
  125. define("focus", "focus", "focus");
  126. define("blur", "blur", "blur");
  127. }
  128. }, '3.4.0' ,{requires:['event-synthetic']});