[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/calendar/yui/src/info/js/ -> info.js (source)

   1  // This file is part of Moodle - http://moodle.org/
   2  //
   3  // Moodle is free software: you can redistribute it and/or modify
   4  // it under the terms of the GNU General Public License as published by
   5  // the Free Software Foundation, either version 3 of the License, or
   6  // (at your option) any later version.
   7  //
   8  // Moodle is distributed in the hope that it will be useful,
   9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11  // GNU General Public License for more details.
  12  //
  13  // You should have received a copy of the GNU General Public License
  14  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  15  
  16  /**
  17   * Overlay manager for the Moodle Calendar.
  18   *
  19   * @module     moodle-core_calendar-info
  20   * @package    core_calendar
  21   * @copyright  2014 Andrew Nicols <andrew@nicols.co.uk>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   * @main       moodle-core_calendar-info
  24   */
  25  
  26  var ARIACONTROLS = 'aria-controls',
  27      BOUNDINGBOX = 'boundingBox',
  28      CALENDAREVENT = '[data-core_calendar-title]',
  29      CALENDARTABLE = 'calendartable',
  30      DATAPREFIX = 'core_calendar-',
  31      DOT = '.',
  32      EVENTCONTENT = 'eventcontent',
  33      EVENTDELAY = 'delay',
  34      EVENTTITLE = 'eventtitle',
  35      INNERHTML = 'innerHTML',
  36  
  37      /**
  38       * Overlay manager for the Moodle calendar.
  39       *
  40       * @namespace M.core_calendar
  41       * @class Info
  42       * @constructor
  43       */
  44  
  45      Info = function() {
  46          Info.superclass.constructor.apply(this, arguments);
  47      };
  48  
  49  
  50  Y.extend(Info, Y.Base, {
  51      /**
  52       * A pointer to the timer used for showing the panel.
  53       *
  54       * @property _showTimer
  55       * @type object
  56       * @private
  57       */
  58      _showTimer: null,
  59  
  60      /**
  61       * A pointer to the timer used for hiding the panel.
  62       *
  63       * @property _hideTimer
  64       * @type object
  65       * @private
  66       */
  67      _hideTimer: null,
  68  
  69      /**
  70       * A pointer for the Calendar Overlay.
  71       *
  72       * @property _panel
  73       * @type object
  74       * @private
  75       */
  76      _panel: null,
  77  
  78      /**
  79       * A pointer to the cell containing the currently open calendar day.
  80       *
  81       * @property _currentDay
  82       * @type object
  83       * @private
  84       */
  85      _currentDay: null,
  86  
  87      initializer: function() {
  88          var body = Y.one(Y.config.doc.body);
  89          body.delegate(['mouseenter', 'focus'], this._startShow, CALENDAREVENT, this);
  90          body.delegate(['mouseleave', 'blur'], this._startHide, CALENDAREVENT, this);
  91      },
  92  
  93      /**
  94       * Initialise the Overlay in which information is displayed.
  95       *
  96       * @method __initOverlay
  97       * @chainable
  98       */
  99      _initOverlay: function() {
 100          if (!this._panel) {
 101              this._panel = new Y.Overlay({
 102                  headerContent: Y.Node.create('<h2 class="' + EVENTTITLE + '"/>'),
 103                  bodyContent: Y.Node.create('<div class="' + EVENTCONTENT + '"/>'),
 104                  visible: false,
 105                  render: true
 106              });
 107  
 108              this._panel.get(BOUNDINGBOX)
 109                  .addClass('calendar-event-panel');
 110          }
 111  
 112          return this;
 113      },
 114  
 115      /**
 116       * Prepare to show the Overlay, and kick off the jobs that cause it to be shown.
 117       *
 118       * @method _startShow
 119       * @param {EventFacade} e
 120       * @private
 121       */
 122      _startShow: function(e) {
 123          if (this._isCurrentDayVisible(e.currentTarget)) {
 124              // Only start the show if the current day isn't already visible.
 125              return;
 126          }
 127  
 128          this._cancelHide()
 129              ._cancelShow()
 130  
 131          // Initialise the panel now - this will only happen once. This way
 132          // it's ready for when the timer times out.
 133              ._initOverlay();
 134  
 135  
 136          this._showTimer = setTimeout(Y.bind(function() {
 137                  var calendarCell = e.target.ancestor(CALENDAREVENT, true);
 138                  this._show(calendarCell);
 139              }, this), this.get(EVENTDELAY));
 140      },
 141  
 142      /**
 143       * Display the Overlay immediately.
 144       *
 145       * @method _show
 146       * @param {Node} dayCell The location that the Overlay should be displayed.
 147       */
 148      _show: function(dayCell) {
 149          var bb = this._panel.get(BOUNDINGBOX),
 150              widgetPositionAlign = Y.WidgetPositionAlign,
 151              calendarParent = dayCell.ancestor(DOT + CALENDARTABLE);
 152  
 153          bb.one(DOT + EVENTTITLE).set(INNERHTML, dayCell.getData(DATAPREFIX + 'title'));
 154          bb.one(DOT + EVENTCONTENT).set(INNERHTML, dayCell.getData(DATAPREFIX + 'popupcontent'));
 155  
 156          // Set the ARIA attributes for the owning cell.
 157          if (this._currentDay) {
 158              this._currentDay.setAttribute(ARIACONTROLS, null);
 159          }
 160          dayCell.setAttribute(ARIACONTROLS, dayCell.get('id'));
 161  
 162          // Move the panel to the current target.
 163          dayCell.appendChild(bb);
 164  
 165          // Keep track of the new day being shown.
 166          this._currentDay = dayCell;
 167  
 168          this._panel.constrain(calendarParent);
 169          this._panel
 170              .set('width', calendarParent.get('offsetWidth') + 'px')
 171              // Align it with the area clicked.
 172              .align(calendarParent, [
 173                      widgetPositionAlign.TC,
 174                      widgetPositionAlign.TC
 175                  ])
 176              // Show it.
 177              .show();
 178  
 179          bb.setAttribute('tabindex', '0')
 180            .focus();
 181      },
 182  
 183      /**
 184       * Cancel the timers which would cause the overlay to be shown.
 185       *
 186       * @method _cancelShow
 187       * @chainable
 188       * @private
 189       */
 190      _cancelShow: function() {
 191          if (this._showTimer) {
 192              clearTimeout(this._showTimer);
 193          }
 194  
 195          return this;
 196      },
 197  
 198      /**
 199       * Prepare to hide the Overlay, and kick off the jobs that cause it to be hidden.
 200       *
 201       * @method _startHide
 202       * @param {EventFacade} e
 203       * @private
 204       */
 205      _startHide: function(e) {
 206          if (e.type === 'blur' && e.currentTarget.contains(e.target)) {
 207              return;
 208          }
 209          this._cancelShow()
 210              ._cancelHide();
 211          this._hideTimer = setTimeout(Y.bind(function() {
 212                  this._hide();
 213              }, this), this.get(EVENTDELAY));
 214      },
 215  
 216      /**
 217       * Hide the Overlay immediately.
 218       *
 219       * @method _hide
 220       */
 221      _hide: function() {
 222          if (this._panel) {
 223              this._panel.hide();
 224          }
 225      },
 226  
 227      /**
 228       * Cancel the timers which would cause the overlay to be hidden.
 229       *
 230       * @method _cancelHide
 231       * @chainable
 232       * @private
 233       */
 234      _cancelHide: function() {
 235          if (this._hideTimer) {
 236              clearTimeout(this._hideTimer);
 237          }
 238  
 239          return this;
 240      },
 241  
 242      /**
 243       * Determine whether the specified day is currently visible.
 244       *
 245       * @method _isCurrentDayVisible
 246       * @param specifiedDay {Node} The Node to check visibility for.
 247       * @private
 248       */
 249      _isCurrentDayVisible: function(specifiedDay) {
 250          if (!this._panel || !this._panel.get('visible')) {
 251              return false;
 252          }
 253  
 254          if (specifiedDay !== this._currentDay) {
 255              return false;
 256          }
 257  
 258          return true;
 259      }
 260  }, {
 261      NAME: 'calendarInfo',
 262      ATTRS: {
 263          /**
 264           * The delay to use before showing or hiding the calendar.
 265           *
 266           * @attribute delay
 267           * @type Number
 268           * @default 300
 269           */
 270          delay: {
 271              value: 300
 272          }
 273      }
 274  });
 275  
 276  Y.namespace('M.core_calendar.info').init = function(config) {
 277      return new Info(config);
 278  };


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