jenkins-bot has submitted this change and it was merged.

Change subject: Add option to trust users
......................................................................


Add option to trust users

Provide a button in the Special:SmiteSpam interface to allow marking a
user as trusted. Pages created by trusted users do not appear in the
list of pages marked as spam.

* Adds an API module "smitespamtrustuser" to allow marking a user as
trusted.
* Adds a special page Special:SmiteSpamTrustedUsers to list the trusted
users and add or remove them.
* Requires running update.php

Change-Id: I4e2e14677f5b02613c2632a2ec9209bd750c8e7a
---
M SmiteSpam.alias.php
A SmiteSpam.hooks.php
M SmiteSpam.php
A SpecialSmiteSpamTrustedUsers.php
A api/SmiteSpamApiTrustUser.php
M autoload.php
M generate-autoloads.php
M i18n/en.json
M i18n/qqq.json
M includes/SmiteSpamAnalyzer.php
M includes/SmiteSpamWikiPage.php
A smitespam.sql
M static/js/ext.smitespam.js
13 files changed, 354 insertions(+), 36 deletions(-)

Approvals:
  jan: Looks good to me, but someone else must approve
  Polybuildr: Looks good to me, approved
  Yaron Koren: Looks good to me, but someone else must approve
  jenkins-bot: Verified



diff --git a/SmiteSpam.alias.php b/SmiteSpam.alias.php
index cbadf13..999ab02 100644
--- a/SmiteSpam.alias.php
+++ b/SmiteSpam.alias.php
@@ -12,4 +12,4 @@
 /** English (English) */
 $specialPageAliases['en'] = array(
        'SmiteSpam' => array( 'SmiteSpam' ),
-);
\ No newline at end of file
+);
diff --git a/SmiteSpam.hooks.php b/SmiteSpam.hooks.php
new file mode 100644
index 0000000..a4c52db
--- /dev/null
+++ b/SmiteSpam.hooks.php
@@ -0,0 +1,10 @@
+<?php
+
+class SmiteSpamHooks {
+       // Schema updates for update.php
+       public static function createTables( DatabaseUpdater $updater ) {
+               $updater->addExtensionTable( 'smitespam_trusted_user',
+                       __DIR__ . '/smitespam.sql' );
+               return true;
+       }
+}
diff --git a/SmiteSpam.php b/SmiteSpam.php
index 8b5841d..5a63909 100644
--- a/SmiteSpam.php
+++ b/SmiteSpam.php
@@ -20,11 +20,15 @@
 $wgMessagesDirs['SmiteSpam'] = "$ssRoot/i18n";
 $wgExtensionMessagesFiles['SmiteSpamAlias'] = "$ssRoot/SmiteSpam.alias.php";
 $wgSpecialPages['SmiteSpam'] = 'SpecialSmiteSpam';
+$wgSpecialPages['SmiteSpamTrustedUsers'] = 'SpecialSmiteSpamTrustedUsers';
 
 $wgAvailableRights[] = 'smitespam';
 $wgGroupPermissions['sysop']['smitespam'] = true;
 
 $wgAPIModules['smitespamanalyze'] = 'SmiteSpamApiQuery';
+$wgAPIModules['smitespamtrustuser'] = 'SmiteSpamApiTrustUser';
+
+$wgHooks['LoadExtensionSchemaUpdates'][] = 'SmiteSpamHooks::createTables';
 
 $wgResourceModules['ext.SmiteSpam.retriever'] = array(
        'scripts' => 'js/ext.smitespam.js',
diff --git a/SpecialSmiteSpamTrustedUsers.php b/SpecialSmiteSpamTrustedUsers.php
new file mode 100644
index 0000000..7f7d5b7
--- /dev/null
+++ b/SpecialSmiteSpamTrustedUsers.php
@@ -0,0 +1,132 @@
+<?php
+
+class SpecialSmiteSpamTrustedUsers extends SpecialPage {
+
+       public function __construct() {
+               parent::__construct( 'SmiteSpamTrustedUsers', 'smitespam' );
+       }
+
+       public function execute( $subPage ) {
+               if ( !$this->userCanExecute( $this->getUser() ) ) {
+                       $this->displayRestrictionError();
+                       return;
+               }
+               $this->setHeaders();
+               $out = $this->getOutput();
+               $request = $this->getRequest();
+
+               if ( $request->wasPosted() ) {
+                       if ( $request->getVal( 'add' ) ) {
+                               $username = $request->getText( 'username' );
+                               $user = User::newFromName( $username );
+                               if ( $user && $user->getId() !== 0 ) {
+                                       $dbr = wfGetDB( DB_SLAVE );
+                                       $result = $dbr->selectRow(
+                                               array( 'smitespam_trusted_user' 
),
+                                               'trusted_user_id',
+                                               array( 'trusted_user_id = ' . 
$user->getId() )
+                                       );
+
+                                       if ( $result ) {
+                                               // TODO i18n
+                                               $out->addHTML(
+                                                       '<div 
class="errorbox">' .
+                                                       "<p>User '$username' 
already trusted.</p>" .
+                                                       '</div>'
+                                               );
+                                       } else {
+                                               $dbw = wfGetDB( DB_MASTER );
+
+                                               $dbw->insert(
+                                                       
'smitespam_trusted_user',
+                                                       array(
+                                                               
'trusted_user_id' => $user->getId(),
+                                                               
'trusted_user_timestamp' => $dbw->timestamp(),
+                                                               
'trusted_user_admin_id' => $this->getUser()->getID()
+                                                       )
+                                               );
+                                               // TODO i18n
+                                               $out->addHTML(
+                                                       '<div 
class="successbox">' .
+                                                       "<p>Trusted user 
'$username'.</p>" .
+                                                       '</div>'
+                                               );
+                                       }
+                               } else {
+                                       // TODO i18n
+                                       $out->addHTML(
+                                               '<div class="errorbox">' .
+                                               "<p>User '$username' does not 
exist.</p>" .
+                                               '</div>'
+                                       );
+                               }
+                       } else {
+                               $usernameToDelete = $request->getText( 'remove' 
);
+                               if ( $usernameToDelete ) {
+                                       $user = User::newFromName( 
$usernameToDelete );
+                                       if ( $user && $user->getId() !== 0 ) {
+                                               $dbw = wfGetDB( DB_MASTER );
+                                               $dbw->delete(
+                                                       
'smitespam_trusted_user',
+                                                       array( 'trusted_user_id 
= ' . $user->getId() )
+                                               );
+                                               // TODO i18n
+                                               $out->addHTML(
+                                                       '<div 
class="successbox">' .
+                                                       "<p>Removed user 
'$usernameToDelete' from trusted users.</p>" .
+                                                       '</div>'
+                                               );
+                                       }
+                               }
+                       }
+               }
+
+               $dbr = wfGetDB( DB_SLAVE );
+               $result = $dbr->select(
+                       array( 'smitespam_trusted_user' ),
+                       array( 'trusted_user_id', 'trusted_user_timestamp', 
'trusted_user_admin_id' ),
+                       array(),
+                       __METHOD__,
+                       array(
+                               "ORDER BY" => "trusted_user_timestamp ASC",
+                       )
+               );
+
+               $out->addHTML( "<form method=\"post\">" );
+
+               $out->addHTML( '<label>Add user: <input type="text" 
name="username"></label>' .
+                       ' <input type="submit" value="Add" name="add">' );
+
+               // TODO i18n
+               $out->addHTML( '<table class="wikitable"><tr>' .
+                       '<th>Trusted User</th>' .
+                       '<th>Timestamp</th>' .
+                       '<th>Trusting Admin</th>' .
+                       '<th>Remove</th>' .
+                       '</tr>'
+               );
+               foreach ( $result as $row ) {
+                       $trustedUser = User::newFromID( $row->trusted_user_id 
)->getName();
+                       $trustedUserContribsLink = Linker::link(
+                               SpecialPage::getTitleFor( 'Contributions', 
$trustedUser ),
+                               Sanitizer::escapeHtmlAllowEntities( 
$trustedUser ),
+                               array( 'target' => '_blank' )
+                       );
+                       $timestamp = wfTimestamp( TS_RFC2822, 
$row->trusted_user_timestamp );
+                       $admin = User::newFromID( $row->trusted_user_admin_id 
)->getName();
+                       $adminContribsLink = Linker::link(
+                               SpecialPage::getTitleFor( 'Contributions', 
$admin ),
+                               Sanitizer::escapeHtmlAllowEntities( $admin ),
+                               array( 'target' => '_blank' )
+                       );
+                       $out->addHTML(
+                               "<tr><td>$trustedUserContribsLink</td>" .
+                               "<td>$timestamp</td>" .
+                               "<td>$adminContribsLink</td>" .
+                               "<td><button type=\"submit\" name=\"remove\" 
value=\"$trustedUser\">Remove</button></tr>"
+                       );
+               }
+               $out->addHTML( '</table>' );
+               $out->addHTML( "</form>" );
+       }
+}
diff --git a/api/SmiteSpamApiTrustUser.php b/api/SmiteSpamApiTrustUser.php
new file mode 100644
index 0000000..9744286
--- /dev/null
+++ b/api/SmiteSpamApiTrustUser.php
@@ -0,0 +1,77 @@
+<?php
+
+class SmiteSpamApiTrustUser extends ApiBase {
+       public function execute() {
+
+               if ( !in_array( 'smitespam', $this->getUser()->getRights() ) ) {
+                       $this->dieUsage( 'Permission error.', 
'permissiondenied' );
+               }
+               $username = $this->getMain()->getVal( 'username' );
+
+               $user = User::newFromName( $username );
+               if ( !$user || $user->getId() === 0 ) {
+                       $this->dieUsage( 'Not a valid username.', 'badparams' );
+               }
+
+               $dbr = wfGetDB( DB_SLAVE );
+
+               $result = $dbr->selectRow(
+                       array( 'smitespam_trusted_user' ),
+                       'trusted_user_id',
+                       array( 'trusted_user_id = ' . $user->getId() )
+               );
+
+               if ( $result ) {
+                       $this->dieUsage( 'User already trusted.', 'duplicate' );
+               }
+
+               $dbw = wfGetDB( DB_MASTER );
+
+               $dbw->insert(
+                       'smitespam_trusted_user',
+                       array(
+                               'trusted_user_id' => $user->getId(),
+                               'trusted_user_timestamp' => $dbw->timestamp(),
+                               'trusted_user_admin_id' => 
$this->getUser()->getID()
+                       )
+               );
+
+               $result = $this->getResult();
+               $result->addValue(
+                       null,
+                       $this->getModuleName(),
+                       array ( 'success' => 1 )
+               );
+               return true;
+       }
+
+       // Description
+       public function getDescription() {
+               return 'Trust a user so that SmiteSpam ignores pages created by 
the user.';
+       }
+
+       // Face parameter.
+       public function getAllowedParams() {
+               return array_merge( parent::getAllowedParams(), array(
+                       'username' => array(
+                               ApiBase::PARAM_TYPE => 'string',
+                               ApiBase::PARAM_REQUIRED => true
+                       )
+               ) );
+       }
+
+       // Describe the parameter
+       public function getParamDescription() {
+               return array_merge( parent::getParamDescription(), array(
+                       'username' => 'Username of user to trust.',
+               ) );
+       }
+
+       // Get examples
+       public function getExamples() {
+               return array(
+                       'api.php?action=smitespamtrustuser&username=Admin'
+                       => 'Trust user "Admin"'
+               );
+       }
+}
diff --git a/autoload.php b/autoload.php
index 8525ea8..395f6a3 100644
--- a/autoload.php
+++ b/autoload.php
@@ -6,10 +6,13 @@
 $wgAutoloadClasses += array(
        'SmiteSpamAnalyzer' => __DIR__ . '/includes/SmiteSpamAnalyzer.php',
        'SmiteSpamApiQuery' => __DIR__ . '/api/SmiteSpamApiQuery.php',
+       'SmiteSpamApiTrustUser' => __DIR__ . '/api/SmiteSpamApiTrustUser.php',
        'SmiteSpamDeleter' => __DIR__ . '/includes/SmiteSpamDeleter.php',
        'SmiteSpamExternalLinksChecker' => __DIR__ . 
'/includes/checkers/SmiteSpamExternalLinksChecker.php',
+       'SmiteSpamHooks' => __DIR__ . '/SmiteSpam.hooks.php',
        'SmiteSpamRepeatedExternalLinksChecker' => __DIR__ . 
'/includes/checkers/SmiteSpamRepeatedExternalLinksChecker.php',
        'SmiteSpamWikiPage' => __DIR__ . '/includes/SmiteSpamWikiPage.php',
        'SmiteSpamWikitextChecker' => __DIR__ . 
'/includes/checkers/SmiteSpamWikitextChecker.php',
        'SpecialSmiteSpam' => __DIR__ . '/SpecialSmiteSpam.php',
+       'SpecialSmiteSpamTrustedUsers' => __DIR__ . 
'/SpecialSmiteSpamTrustedUsers.php',
 );
diff --git a/generate-autoloads.php b/generate-autoloads.php
index c2b34de..829b250 100644
--- a/generate-autoloads.php
+++ b/generate-autoloads.php
@@ -5,6 +5,8 @@
 $gen = new AutoloadGenerator( __DIR__ );
 
 $gen->readFile( __DIR__ . '/SpecialSmiteSpam.php' );
+$gen->readFile( __DIR__ . '/SpecialSmiteSpamTrustedUsers.php' );
+$gen->readFile( __DIR__ . '/SmiteSpam.hooks.php' );
 $gen->readDir( __DIR__ . '/includes' );
 $gen->readDir( __DIR__ . '/api' );
 
diff --git a/i18n/en.json b/i18n/en.json
index 41cac73..1bd716a 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -21,5 +21,6 @@
        "smitespam-probability-medium": "Medium",
        "smitespam-probability-high": "High",
        "smitespam-probability-very-high": "Very high",
-       "smitespam-select": "Select: "
+       "smitespam-select": "Select: ",
+       "smitespamtrustedusers": "SmiteSpam Trusted Users"
 }
diff --git a/i18n/qqq.json b/i18n/qqq.json
index b17e47f..ed7866e 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -23,5 +23,6 @@
        "smitespam-probability-medium": "Medium 
probability\n{{Identical|Medium}}",
        "smitespam-probability-high": "High probability\n{{Identical|High}}",
        "smitespam-probability-very-high": "Very high probability",
-       "smitespam-select": "Followed by two links: 
{{msg-mw|Powersearch-toggleall}} and {{msg-mw|Powersearch-togglenone}} which 
respectively selects all pages and de-selects all pages\n{{Identical|Select}}"
+       "smitespam-select": "Followed by two links: 
{{msg-mw|Powersearch-toggleall}} and {{msg-mw|Powersearch-togglenone}} which 
respectively selects all pages and de-selects all pages\n{{Identical|Select}}",
+       "smitespamtrustedusers": "Title of the Special:SmiteSpamTrustedUsers 
page"
 }
diff --git a/includes/SmiteSpamAnalyzer.php b/includes/SmiteSpamAnalyzer.php
index 908c9ed..7dd45c4 100644
--- a/includes/SmiteSpamAnalyzer.php
+++ b/includes/SmiteSpamAnalyzer.php
@@ -32,6 +32,17 @@
        public function run( $offset = 0, $limit = 500 ) {
                $dbr = wfGetDB( DB_SLAVE );
 
+               $usersResult = $dbr->select(
+                       array( 'smitespam_trusted_user' ),
+                       'trusted_user_id'
+               );
+
+               $trustedUsers = array();
+
+               foreach ( $usersResult as $row ) {
+                       $trustedUsers[] = $row->trusted_user_id;
+               }
+
                $result = $dbr->select(
                        array( 'page' ),
                        'page_id',
@@ -65,6 +76,12 @@
                                continue;
                        }
 
+                       $creatorID = $page->getOldestRevision()->getUser( 
Revision::RAW );
+
+                       if ( in_array( $creatorID, $trustedUsers ) ) {
+                               continue;
+                       }
+
                        if ( $this->config['ignorePagesWithNoExternalLinks']
                            && count( $page->getMetadata( 'externalLinks' ) ) 
== 0 ) {
                            continue;
diff --git a/includes/SmiteSpamWikiPage.php b/includes/SmiteSpamWikiPage.php
index 1d2014a..297a2cb 100644
--- a/includes/SmiteSpamWikiPage.php
+++ b/includes/SmiteSpamWikiPage.php
@@ -10,6 +10,12 @@
        private $metadata;
 
        /**
+        * The Revision object of the oldest revision
+        * @var Revision|null
+        */
+       private $oldestRevision;
+
+       /**
         * A probability-like value representing how likely this page is a spam 
page.
         * @var float
         */
@@ -27,6 +33,13 @@
                $this->metadata = array();
        }
 
+       public function getOldestRevision() {
+               if ( !$this->oldestRevision ) {
+                       $this->oldestRevision = parent::getOldestRevision();
+               }
+               return $this->oldestRevision;
+       }
+
        /**
         * Return particular field of metadata
         * @param  string $key
diff --git a/smitespam.sql b/smitespam.sql
new file mode 100644
index 0000000..0d82bc3
--- /dev/null
+++ b/smitespam.sql
@@ -0,0 +1,15 @@
+--
+-- List of trusted users for SmiteSpam to ignore
+--
+CREATE TABLE /*_*/smitespam_trusted_user (
+       -- User ids of trusted users
+       trusted_user_id int unsigned NOT NULL,
+
+       -- Timestamp of when a user was marked as trusted
+       trusted_user_timestamp binary(14) NOT NULL default '',
+
+       -- User ID of admin who marked a user as trusted
+       trusted_user_admin_id int unsigned NOT NULL
+) /*$wgDBTableOptions*/;
+
+CREATE UNIQUE INDEX /*i*/trusted_user_id ON /*_*/smitespam_trusted_user 
(trusted_user_id);
diff --git a/static/js/ext.smitespam.js b/static/js/ext.smitespam.js
index d21b0fc..34a0f81 100644
--- a/static/js/ext.smitespam.js
+++ b/static/js/ext.smitespam.js
@@ -41,10 +41,17 @@
                        ajaxQueries.pages.numSent++;
                },
                processResponse: function ( data ) {
-                       var receivedPages = data.smitespamanalyze.pages;
-                       $.extend( users, data.smitespamanalyze.users );
-                       $.merge( results, receivedPages );
-                       displayResults();
+                       if ( 'smitespamanalyze' in data ) {
+                               var receivedPages = data.smitespamanalyze.pages;
+                               $.extend( users, data.smitespamanalyze.users );
+                               $.merge( results, receivedPages );
+                               displayResults();
+                       } else if ( 'error' in data ) {
+                               if ( data.error.code === 
'internal_api_error_DBQueryError' ) {
+                                       createErrorbox();
+                                       $( '<p>' ).text( 'Database error! Did 
you forget to run maintenance/update.php?' ).appendTo( '#ajax-errorbox' );
+                               }
+                       }
                }
        };
 
@@ -78,12 +85,7 @@
                                        row.remove();
                                }
                                refreshRangeDisplayer();
-                               if ( $( '#ajax-successbox' ).length === 0 ) {
-                                       var $successbox = $( '<div>', { id: 
'ajax-successbox' } )
-                                               .addClass( 'successbox' );
-                                       $( '#pagination' ).append( $successbox 
);
-                                       $( '#pagination' ).append( '<br>' );
-                               }
+                               createSuccessbox();
                                // TODO i18n
                                $( '#ajax-successbox' ).append( '<p>Page "' + 
pageTitleText + '" deleted.</p>' );
                        } else if ( 'error' in data ) {
@@ -91,12 +93,7 @@
                                if ( row.length ) {
                                        row.find( 'td' ).eq( 3 ).text( mw.msg( 
'smitespam-delete-page-failure-msg' ) );
                                }
-                               if ( $( '#ajax-errorbox' ).length === 0 ) {
-                                       var $errorbox = $( '<div>', { id: 
'ajax-errorbox' } )
-                                               .addClass( 'errorbox' );
-                                       $( '#pagination' ).append( $errorbox );
-                                       $( '#pagination' ).append( '<br>' );
-                               }
+                               createErrorbox();
                                // TODO i18n
                                $( '#ajax-errorbox' ).append( '<p>Failed to 
delete page "' + pageTitleText + '".</p>' );
                        }
@@ -133,18 +130,14 @@
                                $( '#smitespam-page-list th 
.block-checkbox-container' ).each( function () {
                                        var $this = $( this );
                                        if ( $this.parent().data( 'username' )  
=== username ) {
+                                               $this.empty();
                                                // TODO i18n
-                                               $this.parent().append( ' 
(Blocked)' );
-                                               $this.remove();
+                                               $this.append( ' &middot; 
(Blocked)' );
+                                               $this.parent().find( 
'.trust-user-button-container' ).remove();
                                                return false;
                                        }
                                } );
-                               if ( $( '#ajax-successbox' ).length === 0 ) {
-                                       var $successbox = $( '<div>', { id: 
'ajax-successbox' } )
-                                               .addClass( 'successbox' );
-                                       $( '#pagination' ).append( $successbox 
);
-                                       $( '#pagination' ).append( '<br>' );
-                               }
+                               createSuccessbox();
                                // TODO i18n
                                $( '#ajax-successbox' ).append( '<p>User "' + 
username + '" blocked.</p>' );
                        } else if ( 'error' in data ) {
@@ -152,18 +145,13 @@
                                $( '#smitespam-page-list 
.block-checkbox-container' ).each( function () {
                                        var $this = $( this );
                                        if ( $this.parent().data( 'username' )  
=== username ) {
+                                               $this.empty();
                                                // TODO i18n
-                                               $this.parent().append( ' 
(Failed to block)' );
-                                               $this.remove();
+                                               $this.append( ' &middot; 
(Failed to block)' );
                                                return false;
                                        }
                                } );
-                               if ( $( '#ajax-errorbox' ).length === 0 ) {
-                                       var $errorbox = $( '<div>', { id: 
'ajax-errorbox' } )
-                                               .addClass( 'errorbox' );
-                                       $( '#pagination' ).append( $errorbox );
-                                       $( '#pagination' ).append( '<br>' );
-                               }
+                               createErrorbox();
                                // TODO i18n
                                $( '#ajax-errorbox' ).append( '<p>Failed to 
block user "' + username + '".</p>' );
                        }
@@ -248,6 +236,34 @@
                        }
                }
 
+               function onTrustUserButtonClick() {
+                       var $this = $( this );
+                       var username = $this
+                               .parent() // button container
+                               .parent() // creator cell
+                               .data( 'username' );
+
+                       $.getJSON( mw.config.get( 'wgScriptPath' ) + 
'/api.php?action=smitespamtrustuser&format=json&username=' + username,
+                               function ( data ) {
+                                       if ( 'smitespamtrustuser' in data ) {
+                                               $this.parent().parent().find( 
'.block-checkbox-container' ).remove();
+                                               // TODO i18n
+                                               $this.parent().append( 
'Trusted' );
+                                               $this.remove();
+                                               createSuccessbox();
+
+                                               $( '#ajax-successbox' ).append( 
'<p>Trusted user "' + username + '".</p>' );
+                                       } else {
+                                               // TODO i18n
+                                               $this.parent().append( 'Failed 
to trust' );
+                                               $this.remove();
+                                               createErrorbox();
+                                               $( '#ajax-errorbox' ).append( 
'<p>Failed to trust user "' + username + '".</p>' );
+                                       }
+                               }
+                       );
+               }
+
                $( '#smitespam-page-list' ).empty();
                for ( i = 0; i < groupedPages.length; i++ ) {
                        var group = groupedPages[i].pages;
@@ -273,11 +289,20 @@
                                        if ( $.inArray( $blockCheckbox.val(), 
usersToBlock ) !== -1 ) {
                                                $blockCheckbox.attr( 'checked', 
'checked' );
                                        }
+                                       $blockCheckboxContainer.append( ' 
&middot; ' );
                                        $blockCheckboxContainer.append( 
$blockCheckbox );
                                        // TODO i18n
                                        $blockCheckboxContainer.append( 'Block' 
);
-                                       $creatorCell.append( ' &middot; ' );
                                        $creatorCell.append( 
$blockCheckboxContainer );
+
+                                       var $trustUserButtonContainer = $( 
'<span>' ).addClass( 'trust-user-button-container' );
+                                       $trustUserButtonContainer.append( ' 
&middot; ' );
+                                       // TODO i18n
+                                       var $trustUserButton = $( '<button>' 
).text( 'Trust' )
+                                               .on( 'click', 
onTrustUserButtonClick );
+
+                                       $trustUserButtonContainer.append( 
$trustUserButton );
+                                       $creatorCell.append( 
$trustUserButtonContainer );
                                }
                        }
                        var $creatorRow = $( '<tr>' ).append( $creatorCell );
@@ -363,6 +388,24 @@
                $( '#smitespam-displayed-range' ).show();
        }
 
+       function createSuccessbox() {
+               if ( $( '#ajax-successbox' ).length === 0 ) {
+                       var $successbox = $( '<div>', { id: 'ajax-successbox' } 
)
+                               .addClass( 'successbox' );
+                       $( '#pagination' ).append( $successbox );
+                       $( '#pagination' ).append( '<br>' );
+               }
+       }
+
+       function createErrorbox() {
+               if ( $( '#ajax-errorbox' ).length === 0 ) {
+                       var $errorbox = $( '<div>', { id: 'ajax-errorbox' } )
+                               .addClass( 'errorbox' );
+                       $( '#pagination' ).append( $errorbox );
+                       $( '#pagination' ).append( '<br>' );
+               }
+       }
+
        function init() {
                var $pagination = $( '#pagination' );
                // TODO i18n

-- 
To view, visit https://gerrit.wikimedia.org/r/225928
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I4e2e14677f5b02613c2632a2ec9209bd750c8e7a
Gerrit-PatchSet: 3
Gerrit-Project: mediawiki/extensions/SmiteSpam
Gerrit-Branch: master
Gerrit-Owner: Polybuildr <[email protected]>
Gerrit-Reviewer: Polybuildr <[email protected]>
Gerrit-Reviewer: Springle <[email protected]>
Gerrit-Reviewer: Yaron Koren <[email protected]>
Gerrit-Reviewer: jan <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to