Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
YUI.add('moodle-core-lockscroll', function (Y, NAME) {
2
 
3
/**
4
 * Provides the ability to lock the scroll for a page, allowing nested
5
 * locking.
6
 *
7
 * @module moodle-core-lockscroll
8
 */
9
 
10
/**
11
 * Provides the ability to lock the scroll for a page.
12
 *
13
 * This is achieved by applying the class 'lockscroll' to the body Node.
14
 *
15
 * Nested widgets are also supported and the scroll lock is only removed
16
 * when the final plugin instance is disabled.
17
 *
18
 * @class M.core.LockScroll
19
 * @extends Plugin.Base
20
 */
21
Y.namespace('M.core').LockScroll = Y.Base.create('lockScroll', Y.Plugin.Base, [], {
22
 
23
    /**
24
     * Whether the LockScroll has been activated.
25
     *
26
     * @property _enabled
27
     * @type Boolean
28
     * @protected
29
     */
30
    _enabled: false,
31
 
32
    /**
33
     * Handle destruction of the lockScroll instance, including disabling
34
     * of the current instance.
35
     *
36
     * @method destructor
37
     */
38
    destructor: function() {
39
        this.disableScrollLock();
40
    },
41
 
42
    /**
43
     * Start locking the page scroll.
44
     *
45
     * This is achieved by applying the lockscroll class to the body Node.
46
     *
47
     * A count of the total number of active, and enabled, lockscroll instances is also kept on
48
     * the body to ensure that premature disabling does not occur.
49
     *
50
     * @method enableScrollLock
51
     * @param {Boolean} forceOnSmallWindow Whether to enable the scroll lock, even for small window sizes.
52
     * @chainable
53
     */
54
    enableScrollLock: function(forceOnSmallWindow) {
55
        if (this.isActive()) {
56
            return;
57
        }
58
 
59
        if (!this.shouldLockScroll(forceOnSmallWindow)) {
60
            return;
61
        }
62
 
63
        this._enabled = true;
64
        var body = Y.one(Y.config.doc.body);
65
 
66
        // Get width of body before turning on lockscroll.
67
        var widthBefore = body.getComputedStyle('width');
68
 
69
        // We use a CSS class on the body to handle the actual locking.
70
        body.addClass('lockscroll');
71
 
72
        // Increase the count of active instances - this is used to ensure that we do not
73
        // remove the locking when parent windows are still open.
74
        // Note: We cannot use getData here because data attributes are sandboxed to the instance that created them.
75
        var currentCount = parseInt(body.getAttribute('data-activeScrollLocks'), 10) || 0,
76
            newCount = currentCount + 1;
77
        body.setAttribute('data-activeScrollLocks', newCount);
78
 
79
        // When initially enabled, set the body max-width to its current width. This
80
        // avoids centered elements jumping because the width changes when scrollbars
81
        // disappear.
82
        if (currentCount === 0) {
83
            body.setStyle('maxWidth', widthBefore);
84
        }
85
 
86
        return this;
87
    },
88
 
89
    /**
90
     * Recalculate whether lock scrolling should be on or off.
91
     *
92
     * @method shouldLockScroll
93
     * @param {Boolean} forceOnSmallWindow Whether to enable the scroll lock, even for small window sizes.
94
     * @return boolean
95
     */
96
    shouldLockScroll: function(forceOnSmallWindow) {
97
        var dialogueHeight = this.get('host').get('boundingBox').get('region').height,
98
            // Most modern browsers use win.innerHeight, but some older versions of IE use documentElement.clientHeight.
99
            // We fall back to 0 if neither can be found which has the effect of disabling scroll locking.
100
            windowHeight = Y.config.win.innerHeight || Y.config.doc.documentElement.clientHeight || 0;
101
 
102
        if (!forceOnSmallWindow && dialogueHeight > (windowHeight - 10)) {
103
            return false;
104
        } else {
105
            return true;
106
        }
107
    },
108
 
109
    /**
110
     * Recalculate whether lock scrolling should be on or off because the size of the dialogue changed.
111
     *
112
     * @method updateScrollLock
113
     * @param {Boolean} forceOnSmallWindow Whether to enable the scroll lock, even for small window sizes.
114
     * @chainable
115
     */
116
    updateScrollLock: function(forceOnSmallWindow) {
117
        // Both these functions already check if scroll lock is active and do the right thing.
118
        if (this.shouldLockScroll(forceOnSmallWindow)) {
119
            this.enableScrollLock(forceOnSmallWindow);
120
        } else {
121
            this.disableScrollLock(true);
122
        }
123
 
124
        return this;
125
    },
126
 
127
    /**
128
     * Stop locking the page scroll.
129
     *
130
     * The instance may be disabled but the scroll lock not removed if other instances of the
131
     * plugin are also active.
132
     *
133
     * @method disableScrollLock
134
     * @chainable
135
     */
136
    disableScrollLock: function(force) {
137
        if (this.isActive()) {
138
            this._enabled = false;
139
 
140
            var body = Y.one(Y.config.doc.body);
141
 
142
            // Decrease the count of active instances.
143
            // Note: We cannot use getData here because data attributes are sandboxed to the instance that created them.
144
            var currentCount = parseInt(body.getAttribute('data-activeScrollLocks'), 10) || 1,
145
                newCount = currentCount - 1;
146
 
147
            if (force || currentCount === 1) {
148
                body.removeClass('lockscroll');
149
                body.setStyle('maxWidth', null);
150
            }
151
 
152
            body.setAttribute('data-activeScrollLocks', currentCount - 1);
153
        }
154
 
155
        return this;
156
    },
157
 
158
    /**
159
     * Return whether scroll locking is active.
160
     *
161
     * @method isActive
162
     * @return Boolean
163
     */
164
    isActive: function() {
165
        return this._enabled;
166
    }
167
 
168
}, {
169
    NS: 'lockScroll',
170
    ATTRS: {
171
    }
172
});
173
 
174
 
175
}, '@VERSION@', {"requires": ["plugin", "base-build"]});