123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- var ProtectionForm = {
- 'existingMatch': false,
- /**
- * Set up the protection chaining interface (i.e. "unlock move permissions" checkbox)
- * on the protection form
- *
- * @param Object opts : parameters with members:
- * tableId Identifier of the table containing UI bits
- * labelText Text to use for the checkbox label
- * numTypes The number of protection types
- * existingMatch True if all the existing expiry times match
- */
- 'init': function( opts ) {
- if( !( document.createTextNode && document.getElementById && document.getElementsByTagName ) )
- return false;
- var box = document.getElementById( opts.tableId );
- if( !box )
- return false;
-
- var boxbody = box.getElementsByTagName('tbody')[0]
- var row = document.createElement( 'tr' );
- boxbody.insertBefore( row, boxbody.firstChild );
- this.existingMatch = opts.existingMatch;
- var cell = document.createElement( 'td' );
- row.appendChild( cell );
- // If there is only one protection type, there is nothing to chain
- if( opts.numTypes > 1 ) {
- var check = document.createElement( 'input' );
- check.id = 'mwProtectUnchained';
- check.type = 'checkbox';
- cell.appendChild( check );
- addClickHandler( check, function() { ProtectionForm.onChainClick(); } );
- cell.appendChild( document.createTextNode( ' ' ) );
- var label = document.createElement( 'label' );
- label.htmlFor = 'mwProtectUnchained';
- label.appendChild( document.createTextNode( opts.labelText ) );
- cell.appendChild( label );
- check.checked = !this.areAllTypesMatching();
- this.enableUnchainedInputs( check.checked );
- }
- this.updateCascadeCheckbox();
- return true;
- },
- /**
- * Sets the disabled attribute on the cascade checkbox depending on the current selected levels
- */
- 'updateCascadeCheckbox': function() {
- // For non-existent titles, there is no cascade option
- if( !document.getElementById( 'mwProtect-cascade' ) ) {
- return;
- }
- var lists = this.getLevelSelectors();
- for( var i = 0; i < lists.length; i++ ) {
- if( lists[i].selectedIndex > -1 ) {
- var items = lists[i].getElementsByTagName( 'option' );
- var selected = items[ lists[i].selectedIndex ].value;
- if( !this.isCascadeableLevel(selected) ) {
- document.getElementById( 'mwProtect-cascade' ).checked = false;
- document.getElementById( 'mwProtect-cascade' ).disabled = true;
- return;
- }
- }
- }
- document.getElementById( 'mwProtect-cascade' ).disabled = false;
- },
- /**
- * Is this protection level cascadeable?
- * @param String level
- *
- * @return boolean
- *
- */
- 'isCascadeableLevel': function( level ) {
- for (var k = 0; k < wgCascadeableLevels.length; k++) {
- if ( wgCascadeableLevels[k] == level ) {
- return true;
- }
- }
- return false;
- },
- /**
- * When protection levels are locked together, update the rest
- * when one action's level changes
- *
- * @param Element source Level selector that changed
- */
- 'updateLevels': function(source) {
- if( !this.isUnchained() )
- this.setAllSelectors( source.selectedIndex );
- this.updateCascadeCheckbox();
- },
- /**
- * When protection levels are locked together, update the
- * expiries when one changes
- *
- * @param Element source expiry input that changed
- */
- 'updateExpiry': function(source) {
- if( !this.isUnchained() ) {
- var expiry = source.value;
- this.forEachExpiryInput(function(element) {
- element.value = expiry;
- });
- }
- var listId = source.id.replace( /^mwProtect-(\w+)-expires$/, 'mwProtectExpirySelection-$1' );
- var list = document.getElementById( listId );
- if (list && list.value != 'othertime' ) {
- if ( this.isUnchained() ) {
- list.value = 'othertime';
- } else {
- this.forEachExpirySelector(function(element) {
- element.value = 'othertime';
- });
- }
- }
- },
- /**
- * When protection levels are locked together, update the
- * expiry lists when one changes and clear the custom inputs
- *
- * @param Element source expiry selector that changed
- */
- 'updateExpiryList': function(source) {
- if( !this.isUnchained() ) {
- var expiry = source.value;
- this.forEachExpirySelector(function(element) {
- element.value = expiry;
- });
- this.forEachExpiryInput(function(element) {
- element.value = '';
- });
- }
- },
- /**
- * Update chain status and enable/disable various bits of the UI
- * when the user changes the "unlock move permissions" checkbox
- */
- 'onChainClick': function() {
- if( this.isUnchained() ) {
- this.enableUnchainedInputs( true );
- } else {
- this.setAllSelectors( this.getMaxLevel() );
- this.enableUnchainedInputs( false );
- }
- this.updateCascadeCheckbox();
- },
- /**
- * Returns true if the named attribute in all objects in the given array are matching
- */
- 'matchAttribute' : function( objects, attrName ) {
- var value = null;
- // Check levels
- for ( var i = 0; i < objects.length; i++ ) {
- var element = objects[i];
- if ( value == null ) {
- value = element[attrName];
- } else {
- if ( value != element[attrName] ) {
- return false;
- }
- }
- }
- return true;
- },
- /**
- * Are all actions protected at the same level, with the same expiry time?
- *
- * @return boolean
- */
- 'areAllTypesMatching': function() {
- return this.existingMatch
- && this.matchAttribute( this.getLevelSelectors(), 'selectedIndex' )
- && this.matchAttribute( this.getExpirySelectors(), 'selectedIndex' )
- && this.matchAttribute( this.getExpiryInputs(), 'value' );
- },
- /**
- * Is protection chaining off?
- *
- * @return bool
- */
- 'isUnchained': function() {
- var element = document.getElementById( 'mwProtectUnchained' );
- return element
- ? element.checked
- : true; // No control, so we need to let the user set both levels
- },
- /**
- * Find the highest protection level in any selector
- */
- 'getMaxLevel': function() {
- var maxIndex = -1;
- this.forEachLevelSelector(function(element) {
- if (element.selectedIndex > maxIndex) {
- maxIndex = element.selectedIndex;
- }
- });
- return maxIndex;
- },
- /**
- * Protect all actions at the specified level
- *
- * @param int index Protection level
- */
- 'setAllSelectors': function(index) {
- this.forEachLevelSelector(function(element) {
- if (element.selectedIndex != index) {
- element.selectedIndex = index;
- }
- });
- },
- /**
- * Apply a callback to each protection selector
- *
- * @param callable func Callback function
- */
- 'forEachLevelSelector': function(func) {
- var selectors = this.getLevelSelectors();
- for (var i = 0; i < selectors.length; i++) {
- func(selectors[i]);
- }
- },
- /**
- * Get a list of all protection selectors on the page
- *
- * @return Array
- */
- 'getLevelSelectors': function() {
- var all = document.getElementsByTagName("select");
- var ours = new Array();
- for (var i = 0; i < all.length; i++) {
- var element = all[i];
- if (element.id.match(/^mwProtect-level-/)) {
- ours[ours.length] = element;
- }
- }
- return ours;
- },
- /**
- * Apply a callback to each expiry input
- *
- * @param callable func Callback function
- */
- 'forEachExpiryInput': function(func) {
- var inputs = this.getExpiryInputs();
- for (var i = 0; i < inputs.length; i++) {
- func(inputs[i]);
- }
- },
- /**
- * Get a list of all expiry inputs on the page
- *
- * @return Array
- */
- 'getExpiryInputs': function() {
- var all = document.getElementsByTagName("input");
- var ours = new Array();
- for (var i = 0; i < all.length; i++) {
- var element = all[i];
- if (element.name.match(/^mwProtect-expiry-/)) {
- ours[ours.length] = element;
- }
- }
- return ours;
- },
- /**
- * Apply a callback to each expiry selector list
- * @param callable func Callback function
- */
- 'forEachExpirySelector': function(func) {
- var inputs = this.getExpirySelectors();
- for (var i = 0; i < inputs.length; i++) {
- func(inputs[i]);
- }
- },
- /**
- * Get a list of all expiry selector lists on the page
- *
- * @return Array
- */
- 'getExpirySelectors': function() {
- var all = document.getElementsByTagName("select");
- var ours = new Array();
- for (var i = 0; i < all.length; i++) {
- var element = all[i];
- if (element.id.match(/^mwProtectExpirySelection-/)) {
- ours[ours.length] = element;
- }
- }
- return ours;
- },
- /**
- * Enable/disable protection selectors and expiry inputs
- *
- * @param boolean val Enable?
- */
- 'enableUnchainedInputs': function(val) {
- var first = true;
- this.forEachLevelSelector(function(element) {
- if (first) {
- first = false;
- } else {
- element.disabled = !val;
- }
- });
- first = true;
- this.forEachExpiryInput(function(element) {
- if (first) {
- first = false;
- } else {
- element.disabled = !val;
- }
- });
- first = true;
- this.forEachExpirySelector(function(element) {
- if (first) {
- first = false;
- } else {
- element.disabled = !val;
- }
- });
- }
- }
|