Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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