[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yui/src/widget-focusafterclose/js/ -> focusafter.js (source)

   1  /**
   2   * Provides support for focusing on different nodes after the Widget is
   3   * hidden.
   4   *
   5   * If the focusOnPreviousTargetAfterHide attribute is true, then the module hooks
   6   * into the show function for that Widget to try and determine which Node
   7   * caused the Widget to be shown.
   8   *
   9   * Alternatively, the focusAfterHide attribute can be passed a Node.
  10   *
  11   * @module moodle-core-widget-focusafterhide
  12   */
  13  
  14  var CAN_RECEIVE_FOCUS_SELECTOR = 'input:not([type="hidden"]), ' +
  15                                   'a[href], button, textarea, select, ' +
  16                                  '[tabindex], [contenteditable="true"]';
  17  
  18  /**
  19   * Provides support for focusing on different nodes after the Widget is
  20   * hidden.
  21   *
  22   * @class M.core.WidgetFocusAfterHide
  23   */
  24  function WidgetFocusAfterHide() {
  25      Y.after(this._bindUIFocusAfterHide, this, 'bindUI');
  26      if (this.get('rendered')) {
  27          this._bindUIFocusAfterHide();
  28      }
  29  }
  30  
  31  WidgetFocusAfterHide.ATTRS = {
  32      /**
  33       * Whether to focus on the target that caused the Widget to be shown.
  34       *
  35       * <em>If this is true, and a valid Node is found, any Node specified to focusAfterHide
  36       * will be ignored.</em>
  37       *
  38       * @attribute focusOnPreviousTargetAfterHide
  39       * @default false
  40       * @type boolean
  41       */
  42      focusOnPreviousTargetAfterHide: {
  43          value: false
  44      },
  45  
  46      /**
  47       * The Node to focus on after hiding the Widget.
  48       *
  49       * <em>Note: If focusOnPreviousTargetAfterHide is true, and a valid Node is found, then this
  50       * value will be ignored. If it is true and not found, then this value will be used as
  51       * a fallback.</em>
  52       *
  53       * @attribute focusAfterHide
  54       * @default null
  55       * @type Node
  56       */
  57      focusAfterHide: {
  58          value: null,
  59          type: Y.Node
  60      }
  61  };
  62  
  63  WidgetFocusAfterHide.prototype = {
  64      /**
  65       * The list of Event Handles which we should cancel when the dialogue is destroyed.
  66       *
  67       * @property uiHandleFocusAfterHide
  68       * @type array
  69       * @protected
  70       */
  71      _uiHandlesFocusAfterHide: [],
  72  
  73      /**
  74       * A reference to the real show method which is being overwritten.
  75       *
  76       * @property _showFocusAfterHide
  77       * @type function
  78       * @default null
  79       * @protected
  80       */
  81      _showFocusAfterHide: null,
  82  
  83      /**
  84       * A reference to the detected previous target.
  85       *
  86       * @property _previousTargetFocusAfterHide
  87       * @type function
  88       * @default null
  89       * @protected
  90       */
  91      _previousTargetFocusAfterHide: null,
  92  
  93      initializer: function() {
  94  
  95          if (this.get('focusOnPreviousTargetAfterHide') && this.show) {
  96              // Overwrite the parent method so that we can get the focused
  97              // target.
  98              this._showFocusAfterHide = this.show;
  99              this.show = function(e) {
 100                  this._showFocusAfterHide.apply(this, arguments);
 101  
 102                  // We use a property rather than overriding the focusAfterHide parameter in
 103                  // case the target cannot be found at hide time.
 104                  this._previousTargetFocusAfterHide = null;
 105                  if (e && e.currentTarget) {
 106                      Y.log("Determined a Node which caused the Widget to be shown",
 107                              'debug', 'moodle-core-widget-focusafterhide');
 108                      this._previousTargetFocusAfterHide = e.currentTarget;
 109                  }
 110              };
 111          }
 112      },
 113  
 114      destructor: function() {
 115          new Y.EventHandle(this.uiHandleFocusAfterHide).detach();
 116      },
 117  
 118      /**
 119       * Set up the event handling required for this module to work.
 120       *
 121       * @method _bindUIFocusAfterHide
 122       * @private
 123       */
 124      _bindUIFocusAfterHide: function() {
 125          // Detach the old handles first.
 126          new Y.EventHandle(this.uiHandleFocusAfterHide).detach();
 127          this.uiHandleFocusAfterHide = [
 128              this.after('visibleChange', this._afterHostVisibleChangeFocusAfterHide)
 129          ];
 130      },
 131  
 132      /**
 133       * Handle the change in UI visibility.
 134       *
 135       * This method changes the focus after the hide has taken place.
 136       *
 137       * @method _afterHostVisibleChangeFocusAfterHide
 138       * @private
 139       */
 140      _afterHostVisibleChangeFocusAfterHide: function() {
 141          if (!this.get('visible')) {
 142              if (this._attemptFocus(this._previousTargetFocusAfterHide)) {
 143                  Y.log("Focusing on the target automatically determined when the Widget was opened",
 144                          'debug', 'moodle-core-widget-focusafterhide');
 145  
 146              } else if (this._attemptFocus(this.get('focusAfterHide'))) {
 147                  // Fall back to the focusAfterHide value if one was specified.
 148                  Y.log("Focusing on the target provided to focusAfterHide",
 149                          'debug', 'moodle-core-widget-focusafterhide');
 150  
 151              } else {
 152                  Y.log("No valid focus target found - not returning focus.",
 153                          'debug', 'moodle-core-widget-focusafterhide');
 154  
 155              }
 156          }
 157      },
 158  
 159      _attemptFocus: function(node) {
 160          var focusTarget = Y.one(node);
 161          if (focusTarget) {
 162              focusTarget = focusTarget.ancestor(CAN_RECEIVE_FOCUS_SELECTOR, true);
 163              if (focusTarget) {
 164                  focusTarget.focus();
 165                  return true;
 166              }
 167          }
 168          return false;
 169      }
 170  };
 171  
 172  var NS = Y.namespace('M.core');
 173  NS.WidgetFocusAfterHide = WidgetFocusAfterHide;


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1