Requires

Provides

Focus.js

A mixin to make widget take focus like a regular input (even in Safari)

License:
Public domain (http://unlicense.org).
Authors:
Yaroslaff Fedin
  1. 25
  2. 26
  3. 27
  4. 28
  5. 29
  6. 30
  7. 31
  8. 32
  9. 33
  10. 34
  11. 35
  12. 36
  13. 37
  14. 38
  15. 39
  16. 40
  17. 41
  18. 42
  19. 43
  20. 44
  21. 45
  22. 46
  23. 47
  24. 48
  25. 49
  26. 50
  27. 51
  28. 52
  29. 53
  30. 54
  31. 55
  32. 56
  33. 57
  34. 58
  35. 59
  36. 60
  37. 61
  38. 62
  39. 63
  40. 64
  41. 65
  42. 66
  43. 67
  44. 68
  45. 69
  46. 70
  47. 71
  48. 72
  49. 73
  50. 74
  51. 75
  52. 76
  53. 77
  54. 78
  55. 79
  56. 80
  57. 81
  58. 82
  59. 83
  60. 84
  61. 85
  62. 86
  63. 87
  64. 88
  65. 89
  66. 90
  67. 91
  68. 92
  69. 93
  70. 94
  71. 95
  72. 96
  73. 97
  74. 98
  75. 99
  76. 100
  77. 101
  78. 102
  79. 103
  80. 104
  81. 105
  82. 106
  83. 107
  84. 108
  85. 109
  86. 110
  87. 111
  88. 112
  89. 113
  90. 114
  91. 115
  92. 116
  93. 117
  94. 118
  95. 119
  96. 120
  97. 121
  98. 122
  99. 123
  100. 124
LSD.Mixin.Focus = new Class({ behaviour: '[tabindex][tabindex!=-1]', options: { actions: { focus: { target: false, enable: function(target) { if (target.tabindex != null) { target.attributes.tabindex = target.tabindex if (target.focuser) target.element.set('tabindex', target.tabindex) delete target.tabindex; } if (target.attributes.tabindex == -1) return; target.getFocuser(); target.addEvents(target.events.focus); target.element.addEvents(target.bindEvents({mousedown: 'retain'})); }, disable: function(target) { target.blur(); if (target.options.tabindex == -1) return; target.tabindex = target.options.tabindex || 0; target.element.set('tabindex', -1) target.attributes.tabindex = -1; target.removeEvents(target.events.focus); target.element.removeEvents(target.bindEvents({mousedown: 'retain'})); } } } }, getFocuser: Macro.getter('focuser', function() { return new QFocuser(this.toElement(), { onWidgetFocus: this.onFocus.bind(this), onWidgetBlur: this.onBlur.bind(this), tabIndex: this.getAttribute('tabindex') }) }), focus: function(element) { if (element !== false) { this.getFocuser().focus(element || this.element); this.document.activeElement = this; } if (this.focused) return; this.focused = true; this.fireEvent('focus', arguments); this.onStateChange('focused', true); LSD.Mixin.Focus.Propagation.focus(this); }, blur: function(propagated) { if (!this.focused) return; this.focused = false; this.fireEvent('blur', arguments); this.onStateChange('focused', false); if (!propagated) LSD.Mixin.Focus.Propagation.blur.delay(10, this, this); }, retain: function(e) { if (e) e.stop(); this.focus(); }, onFocus: Macro.defaults(function() { this.focus(false); this.document.activeElement = this; }), onBlur: Macro.defaults(function() { var active = this.document.activeElement; if (active == this) delete this.document.activeElement; while (active && (active = active.parentNode)) if (active == this) return; this.blur(); }), getKeyListener: function() { return this.getFocuser().getKeyListener() } }); LSD.Mixin.Focus.Propagation = { focus: function(parent) { while (parent = parent.parentNode) if (parent.getFocuser) parent.focus(false); }, blur: function(parent) { var active = parent.document.activeElement; var hierarchy = []; if (active) { var widget = active; while (widget.parentNode) hierarchy.unshift(widget = widget.parentNode); } while (parent = parent.parentNode) { if (active && hierarchy.contains(parent)) break; if (parent.options && (parent.options.tabindex != null) && parent.blur) parent.blur(true); } } };