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