Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
918 ariadna 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
 * Contain the logic for a drawer.
18
 *
19
 * @module theme_universe/drawer
20
 * @copyright  2016 Damyon Wiese
21
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22
 */
23
define([
24
  "jquery",
25
  "core/custom_interaction_events",
26
  "core/log",
27
  "core/pubsub",
28
  "core/aria",
29
  "core_user/repository",
30
], function ($, CustomEvents, Log, PubSub, Aria, UserRepository) {
31
  var SELECTORS = {
32
    TOGGLE_REGION: '[data-region="drawer-toggle"]',
33
    TOGGLE_ACTION: '[data-action="toggle-drawer"]',
34
    TOGGLE_TARGET: "aria-controls",
35
    TOGGLE_SIDE: "left",
36
    BODY: "body",
37
    SECTION: '.list-group-item[href*="#section-"]',
38
    DRAWER: "#nav-drawer",
39
  };
40
 
41
  var small = $(document).width() < 768;
42
 
43
  /**
44
   * Constructor for the Drawer.
45
   */
46
  var Drawer = function () {
47
    if (!$(SELECTORS.TOGGLE_REGION).length) {
48
      Log.debug("Page is missing a drawer region");
49
    }
50
    if (!$(SELECTORS.TOGGLE_ACTION).length) {
51
      Log.debug("Page is missing a drawer toggle link");
52
    }
53
    $(SELECTORS.TOGGLE_REGION).each(
54
      function (index, ele) {
55
        var trigger = $(ele).find(SELECTORS.TOGGLE_ACTION);
56
        var drawerid = trigger.attr("aria-controls");
57
        var drawer = $(document.getElementById(drawerid));
58
        var hidden = trigger.attr("aria-expanded") == "false";
59
        var side = trigger.attr("data-side");
60
        var body = $(SELECTORS.BODY);
61
        var preference = trigger.attr("data-preference");
62
        if (small) {
63
          UserRepository.setUserPreference(preference, false);
64
        }
65
 
66
        drawer.on("mousewheel DOMMouseScroll", this.preventPageScroll);
67
 
68
        if (!hidden) {
69
          body.addClass("drawer-open-" + side);
70
          trigger.attr("aria-expanded", "true");
71
        } else {
72
          trigger.attr("aria-expanded", "false");
73
        }
74
      }.bind(this)
75
    );
76
 
77
    this.registerEventListeners();
78
    if (small) {
79
      this.closeAll();
80
    }
81
  };
82
 
83
  Drawer.prototype.closeAll = function () {
84
    $(SELECTORS.TOGGLE_REGION).each(function (index, ele) {
85
      var trigger = $(ele).find(SELECTORS.TOGGLE_ACTION);
86
      var side = trigger.attr("data-side");
87
      var body = $(SELECTORS.BODY);
88
      var drawerid = trigger.attr("aria-controls");
89
      var drawer = $(document.getElementById(drawerid));
90
      var preference = trigger.attr("data-preference");
91
 
92
      trigger.attr("aria-expanded", "false");
93
      body.removeClass("drawer-open-" + side);
94
      Aria.hide(drawer.get());
95
      drawer.addClass("closed");
96
      if (!small) {
97
        UserRepository.setUserPreference(preference, false);
98
      }
99
    });
100
  };
101
 
102
  /**
103
   * Open / close the blocks drawer.
104
   *
105
   * @method toggleDrawer
106
   * @param {Event} e
107
   */
108
  Drawer.prototype.toggleDrawer = function (e) {
109
    var trigger = $(e.target).closest("[data-action=toggle-drawer]");
110
    var drawerid = trigger.attr("aria-controls");
111
    var drawer = $(document.getElementById(drawerid));
112
    var body = $(SELECTORS.BODY);
113
    var side = trigger.attr("data-side");
114
    var preference = trigger.attr("data-preference");
115
    if (small) {
116
      UserRepository.setUserPreference(preference, false);
117
    }
118
 
119
    body.addClass("drawer-ease");
120
    var open = trigger.attr("aria-expanded") == "true";
121
    if (!open) {
122
      // Open.
123
      trigger.attr("aria-expanded", "true");
124
      Aria.unhide(drawer.get());
125
      drawer.focus();
126
      body.addClass("drawer-open-" + side);
127
      drawer.removeClass("closed");
128
      if (!small) {
129
        UserRepository.setUserPreference(preference, true);
130
      }
131
    } else {
132
      // Close.
133
      body.removeClass("drawer-open-" + side);
134
      trigger.attr("aria-expanded", "false");
135
      drawer
136
        .addClass("closed")
137
        .delay(500)
138
        .queue(function () {
139
          // Ensure that during the delay, the drawer wasn't re-opened.
140
          if ($(this).hasClass("closed")) {
141
            Aria.hide(this);
142
          }
143
          $(this).dequeue();
144
        });
145
      if (!small) {
146
        UserRepository.setUserPreference(preference, false);
147
      }
148
    }
149
 
150
    // Publish an event to tell everything that the drawer has been toggled.
151
    // The drawer transitions closed so another event will fire once teh transition
152
    // has completed.
153
    PubSub.publish("nav-drawer-toggle-start", open);
154
  };
155
 
156
  /**
157
   * Prevent the page from scrolling when the drawer is at max scroll.
158
   *
159
   * @method preventPageScroll
160
   * @param  {Event} e
161
   */
162
  Drawer.prototype.preventPageScroll = function (e) {
163
    var delta =
164
        e.wheelDelta ||
165
        (e.originalEvent && e.originalEvent.wheelDelta) ||
166
        -e.originalEvent.detail,
167
      bottomOverflow =
168
        this.scrollTop + $(this).outerHeight() - this.scrollHeight >= 0,
169
      topOverflow = this.scrollTop <= 0;
170
 
171
    if ((delta < 0 && bottomOverflow) || (delta > 0 && topOverflow)) {
172
      e.preventDefault();
173
    }
174
  };
175
 
176
  /**
177
   * Set up all of the event handling for the modal.
178
   *
179
   * @method registerEventListeners
180
   */
181
  Drawer.prototype.registerEventListeners = function () {
182
    $(SELECTORS.TOGGLE_ACTION).each(
183
      function (index, element) {
184
        CustomEvents.define($(element), [CustomEvents.events.activate]);
185
        $(element).on(
186
          CustomEvents.events.activate,
187
          function (e, data) {
188
            this.toggleDrawer(data.originalEvent);
189
            data.originalEvent.preventDefault();
190
          }.bind(this)
191
        );
192
      }.bind(this)
193
    );
194
 
195
    $(SELECTORS.SECTION).click(
196
      function () {
197
        if (small) {
198
          this.closeAll();
199
        }
200
      }.bind(this)
201
    );
202
 
203
    // Publish an event to tell everything that the drawer completed the transition
204
    // to either an open or closed state.
205
    $(SELECTORS.DRAWER).on(
206
      "webkitTransitionEnd msTransitionEnd transitionend",
207
      function (e) {
208
        var drawer = $(e.target).closest(SELECTORS.DRAWER);
209
        // Note: aria-hidden is either present, or absent. It should not be set to false.
210
        var open = !!drawer.attr("aria-hidden");
211
        PubSub.publish("nav-drawer-toggle-end", open);
212
      }
213
    );
214
  };
215
 
216
  return {
217
    init: function () {
218
      return new Drawer();
219
    },
220
  };
221
});