MDL-42928 JavaScript: Create a module to handle page scroll locking

This commit is contained in:
Andrew Nicols 2013-11-16 08:54:22 +08:00
parent 9788e26805
commit 5ab39a0e97
9 changed files with 401 additions and 1 deletions

View File

@ -0,0 +1,128 @@
YUI.add('moodle-core-lockscroll', function (Y, NAME) {
/**
* Provides the ability to lock the scroll for a page, allowing nested
* locking.
*
* @module moodle-core-lockscroll
*/
/**
* Provides the ability to lock the scroll for a page.
*
* This is achieved by applying the class 'lockscroll' to the body Node.
*
* Nested widgets are also supported and the scroll lock is only removed
* when the final plugin instance is disabled.
*
* @class M.core.LockScroll
* @extends Plugin.Base
*/
Y.namespace('M.core').LockScroll = Y.Base.create('lockScroll', Y.Plugin.Base, [], {
/**
* Whether the LockScroll has been activated.
*
* @property _enabled
* @type Boolean
* @protected
*/
_enabled: false,
/**
* Handle destruction of the lockScroll instance, including disabling
* of the current instance.
*
* @method destructor
*/
destructor: function() {
this.disableScrollLock();
},
/**
* Start locking the page scroll.
*
* This is achieved by applying the lockscroll class to the body Node.
*
* A count of the total number of active, and enabled, lockscroll instances is also kept on
* the body to ensure that premature disabling does not occur.
*
* @method enableScrollLock
* @chainable
*/
enableScrollLock: function() {
if (this.isActive()) {
Y.log('LockScroll already active. Ignoring enable request', 'warn', 'moodle-core-lockscroll');
return;
}
Y.log('Enabling LockScroll.', 'debug', 'moodle-core-lockscroll');
this._enabled = true;
var body = Y.one(Y.config.doc.body);
// We use a CSS class on the body to handle the actual locking.
body.addClass('lockscroll');
// Increase the count of active instances - this is used to ensure that we do not
// remove the locking when parent windows are still open.
// Note: We cannot use getData here because data attributes are sandboxed to the instance that created them.
var currentCount = parseInt(body.getAttribute('data-activeScrollLocks'), 10) || 0,
newCount = currentCount + 1;
body.setAttribute('data-activeScrollLocks', newCount);
Y.log("Setting the activeScrollLocks count from " + currentCount + " to " + newCount,
'debug', 'moodle-core-lockscroll');
return this;
},
/**
* Stop locking the page scroll.
*
* The instance may be disabled but the scroll lock not removed if other instances of the
* plugin are also active.
*
* @method disableScrollLock
* @chainable
*/
disableScrollLock: function() {
if (this.isActive()) {
Y.log('Disabling LockScroll.', 'debug', 'moodle-core-lockscroll');
this._enabled = false;
var body = Y.one(Y.config.doc.body);
// Decrease the count of active instances.
// Note: We cannot use getData here because data attributes are sandboxed to the instance that created them.
var currentCount = parseInt(body.getAttribute('data-activeScrollLocks'), 10) || 1,
newCount = currentCount - 1;
if (currentCount === 1) {
body.removeClass('lockscroll');
}
body.setAttribute('data-activeScrollLocks', currentCount - 1);
Y.log("Setting the activeScrollLocks count from " + currentCount + " to " + newCount,
'debug', 'moodle-core-lockscroll');
}
return this;
},
/**
* Return whether scroll locking is active.
*
* @method isActive
* @return Boolean
*/
isActive: function() {
return this._enabled;
}
}, {
NS: 'lockScroll',
ATTRS: {
}
});
}, '@VERSION@', {"requires": ["plugin", "base-build"]});

View File

@ -0,0 +1 @@
YUI.add("moodle-core-lockscroll",function(e,t){e.namespace("M.core").LockScroll=e.Base.create("lockScroll",e.Plugin.Base,[],{_enabled:!1,destructor:function(){this.disableScrollLock()},enableScrollLock:function(){if(this.isActive())return;this._enabled=!0;var t=e.one(e.config.doc.body);t.addClass("lockscroll");var n=parseInt(t.getAttribute("data-activeScrollLocks"),10)||0,r=n+1;return t.setAttribute("data-activeScrollLocks",r),this},disableScrollLock:function(){if(this.isActive()){this._enabled=!1;var t=e.one(e.config.doc.body),n=parseInt(t.getAttribute("data-activeScrollLocks"),10)||1,r=n-1;n===1&&t.removeClass("lockscroll"),t.setAttribute("data-activeScrollLocks",n-1)}return this},isActive:function(){return this._enabled}},{NS:"lockScroll",ATTRS:{}})},"@VERSION@",{requires:["plugin","base-build"]});

View File

@ -0,0 +1,121 @@
YUI.add('moodle-core-lockscroll', function (Y, NAME) {
/**
* Provides the ability to lock the scroll for a page, allowing nested
* locking.
*
* @module moodle-core-lockscroll
*/
/**
* Provides the ability to lock the scroll for a page.
*
* This is achieved by applying the class 'lockscroll' to the body Node.
*
* Nested widgets are also supported and the scroll lock is only removed
* when the final plugin instance is disabled.
*
* @class M.core.LockScroll
* @extends Plugin.Base
*/
Y.namespace('M.core').LockScroll = Y.Base.create('lockScroll', Y.Plugin.Base, [], {
/**
* Whether the LockScroll has been activated.
*
* @property _enabled
* @type Boolean
* @protected
*/
_enabled: false,
/**
* Handle destruction of the lockScroll instance, including disabling
* of the current instance.
*
* @method destructor
*/
destructor: function() {
this.disableScrollLock();
},
/**
* Start locking the page scroll.
*
* This is achieved by applying the lockscroll class to the body Node.
*
* A count of the total number of active, and enabled, lockscroll instances is also kept on
* the body to ensure that premature disabling does not occur.
*
* @method enableScrollLock
* @chainable
*/
enableScrollLock: function() {
if (this.isActive()) {
return;
}
this._enabled = true;
var body = Y.one(Y.config.doc.body);
// We use a CSS class on the body to handle the actual locking.
body.addClass('lockscroll');
// Increase the count of active instances - this is used to ensure that we do not
// remove the locking when parent windows are still open.
// Note: We cannot use getData here because data attributes are sandboxed to the instance that created them.
var currentCount = parseInt(body.getAttribute('data-activeScrollLocks'), 10) || 0,
newCount = currentCount + 1;
body.setAttribute('data-activeScrollLocks', newCount);
return this;
},
/**
* Stop locking the page scroll.
*
* The instance may be disabled but the scroll lock not removed if other instances of the
* plugin are also active.
*
* @method disableScrollLock
* @chainable
*/
disableScrollLock: function() {
if (this.isActive()) {
this._enabled = false;
var body = Y.one(Y.config.doc.body);
// Decrease the count of active instances.
// Note: We cannot use getData here because data attributes are sandboxed to the instance that created them.
var currentCount = parseInt(body.getAttribute('data-activeScrollLocks'), 10) || 1,
newCount = currentCount - 1;
if (currentCount === 1) {
body.removeClass('lockscroll');
}
body.setAttribute('data-activeScrollLocks', currentCount - 1);
}
return this;
},
/**
* Return whether scroll locking is active.
*
* @method isActive
* @return Boolean
*/
isActive: function() {
return this._enabled;
}
}, {
NS: 'lockScroll',
ATTRS: {
}
});
}, '@VERSION@', {"requires": ["plugin", "base-build"]});

View File

@ -0,0 +1,10 @@
{
"name": "moodle-core-lockscroll",
"builds": {
"moodle-core-lockscroll": {
"jsfiles": [
"lockscroll.js"
]
}
}
}

123
lib/yui/src/lockscroll/js/lockscroll.js vendored Normal file
View File

@ -0,0 +1,123 @@
/**
* Provides the ability to lock the scroll for a page, allowing nested
* locking.
*
* @module moodle-core-lockscroll
*/
/**
* Provides the ability to lock the scroll for a page.
*
* This is achieved by applying the class 'lockscroll' to the body Node.
*
* Nested widgets are also supported and the scroll lock is only removed
* when the final plugin instance is disabled.
*
* @class M.core.LockScroll
* @extends Plugin.Base
*/
Y.namespace('M.core').LockScroll = Y.Base.create('lockScroll', Y.Plugin.Base, [], {
/**
* Whether the LockScroll has been activated.
*
* @property _enabled
* @type Boolean
* @protected
*/
_enabled: false,
/**
* Handle destruction of the lockScroll instance, including disabling
* of the current instance.
*
* @method destructor
*/
destructor: function() {
this.disableScrollLock();
},
/**
* Start locking the page scroll.
*
* This is achieved by applying the lockscroll class to the body Node.
*
* A count of the total number of active, and enabled, lockscroll instances is also kept on
* the body to ensure that premature disabling does not occur.
*
* @method enableScrollLock
* @chainable
*/
enableScrollLock: function() {
if (this.isActive()) {
Y.log('LockScroll already active. Ignoring enable request', 'warn', 'moodle-core-lockscroll');
return;
}
Y.log('Enabling LockScroll.', 'debug', 'moodle-core-lockscroll');
this._enabled = true;
var body = Y.one(Y.config.doc.body);
// We use a CSS class on the body to handle the actual locking.
body.addClass('lockscroll');
// Increase the count of active instances - this is used to ensure that we do not
// remove the locking when parent windows are still open.
// Note: We cannot use getData here because data attributes are sandboxed to the instance that created them.
var currentCount = parseInt(body.getAttribute('data-activeScrollLocks'), 10) || 0,
newCount = currentCount + 1;
body.setAttribute('data-activeScrollLocks', newCount);
Y.log("Setting the activeScrollLocks count from " + currentCount + " to " + newCount,
'debug', 'moodle-core-lockscroll');
return this;
},
/**
* Stop locking the page scroll.
*
* The instance may be disabled but the scroll lock not removed if other instances of the
* plugin are also active.
*
* @method disableScrollLock
* @chainable
*/
disableScrollLock: function() {
if (this.isActive()) {
Y.log('Disabling LockScroll.', 'debug', 'moodle-core-lockscroll');
this._enabled = false;
var body = Y.one(Y.config.doc.body);
// Decrease the count of active instances.
// Note: We cannot use getData here because data attributes are sandboxed to the instance that created them.
var currentCount = parseInt(body.getAttribute('data-activeScrollLocks'), 10) || 1,
newCount = currentCount - 1;
if (currentCount === 1) {
body.removeClass('lockscroll');
}
body.setAttribute('data-activeScrollLocks', currentCount - 1);
Y.log("Setting the activeScrollLocks count from " + currentCount + " to " + newCount,
'debug', 'moodle-core-lockscroll');
}
return this;
},
/**
* Return whether scroll locking is active.
*
* @method isActive
* @return Boolean
*/
isActive: function() {
return this._enabled;
}
}, {
NS: 'lockScroll',
ATTRS: {
}
});

View File

@ -0,0 +1,8 @@
{
"moodle-core-lockscroll": {
"requires": [
"plugin",
"base-build"
]
}
}

View File

@ -1800,3 +1800,8 @@ a:hover .caret {
-o-animation: progress-bar-stripes 2s linear infinite;
animation: progress-bar-stripes 2s linear infinite;
}
body.lockscroll {
height: 100%;
overflow: hidden;
}

View File

@ -2231,3 +2231,7 @@ a.disabled {
font-style: italic;
color: #808080;
}
body.lockscroll {
height: 100%;
overflow: hidden;
}

File diff suppressed because one or more lines are too long