[ Index ]

PHP Cross Reference of moodle-2.8

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


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1