MarkAHershberger has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/398618 )

Change subject: Refactor and bump version to 1.3
......................................................................

Refactor and bump version to 1.3

* Address any phpcs issues.
* Put everything in MediaWiki\Extension\ReplaceText namespace.
* Break up big functions into smaller bite-size pieces.
* Create and use modules for CSS and JS.
* Assign my copyright to NicheWork LLC

Change-Id: I251188efa2fc1fbf0563b0e1f792a912d077d8c9
---
M README
A ReplaceText.css
M ReplaceText.hooks.php
M ReplaceText.js
M ReplaceText.php
M ReplaceTextJob.php
A ReplaceTextSearch.js
M ReplaceTextSearch.php
M SpecialReplaceText.php
M extension.json
M replaceAll.php
11 files changed, 1,141 insertions(+), 468 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/ReplaceText 
refs/changes/18/398618/1

diff --git a/README b/README
index 1e0859b..95bdc72 100644
--- a/README
+++ b/README
@@ -1,6 +1,6 @@
 Replace Text Extension
 
-        Version 1.2
+        Version 1.3
         Yaron Koren and Niklas Laxström
 
 This is free software licenced under the GNU General Public Licence. Please
diff --git a/ReplaceText.css b/ReplaceText.css
new file mode 100644
index 0000000..2b65254
--- /dev/null
+++ b/ReplaceText.css
@@ -0,0 +1,4 @@
+.rt-searchmatch {
+    font-weight: bold;
+    font-size: 1.4em;
+}
diff --git a/ReplaceText.hooks.php b/ReplaceText.hooks.php
index 4edf513..636cb1c 100644
--- a/ReplaceText.hooks.php
+++ b/ReplaceText.hooks.php
@@ -1,11 +1,40 @@
 <?php
 /**
+ * Hook for AdminLinks
+ *
+ * Copyright (C) 2015  Yaron Koren
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
  */
 
-class ReplaceTextHooks {
+namespace MediaWiki\\Extension\\ReplaceText;
 
-       public static function addToAdminLinks( ALTree &$adminLinksTree ) {
-               $generalSection = $adminLinksTree->getSection( wfMessage( 
'adminlinks_general' )->text() );
+use ALTree;
+use ALRow;
+
+class Hook {
+
+       /**
+        * Hook for AdminLinks to include ReplaceText
+        * @param ALTree $adminLinksTree the tree
+        */
+       public static function addToAdminLinks( ALTree $adminLinksTree ) {
+               $generalSection = $adminLinksTree->getSection(
+                       wfMessage( 'adminlinks_general' )->text()
+               );
                $extensionsRow = $generalSection->getRow( 'extensions' );
 
                if ( is_null( $extensionsRow ) ) {
@@ -14,8 +43,6 @@
                }
 
                $extensionsRow->addItem( ALItem::newFromSpecialPage( 
'ReplaceText' ) );
-
-               return true;
        }
 
 }
diff --git a/ReplaceText.js b/ReplaceText.js
index 666c462..9efc327 100644
--- a/ReplaceText.js
+++ b/ReplaceText.js
@@ -1,17 +1,27 @@
-function invertSelections() {
-       'use strict';
+/* @license GPL 2.0 */
+/* @author Yaron Koren */
+( function ( mw, $ ) {
+       $( function () {
+               invertSelections = function() {
+                       'use strict';
 
-       var form = document.getElementById('choose_pages' ),
-               num_elements = form.elements.length,
-               i,
-               cur_element;
+                       var form = document.getElementById( 'choose_pages' ),
+                       num_elements = form.elements.length,
+                       i,
+                       cur_element;
 
-       for (i = 0; i < num_elements; i++) {
-               cur_element = form.elements[i];
+                       for ( i = 0; i < num_elements; i++ ) {
+                               cur_element = form.elements[i];
 
-               if (cur_element.type === "checkbox" && cur_element.id !== 
'create-redirect' &&
-                       cur_element.id !== 'watch-pages' && cur_element.id !== 
'doEnotif' ) {
-                       form.elements[i].checked = form.elements[i].checked !== 
true;
-               }
-       }
-}
+                               if (
+                                       cur_element.type === "checkbox" &&
+                                               cur_element.id !== 
'create-redirect' &&
+                                               cur_element.id !== 
'watch-pages' &&
+                                               cur_element.id !== 'doEnotif'
+                               ) {
+                                       form.elements[i].checked = 
form.elements[i].checked !== true;
+                               }
+                       }
+               };
+       } );
+}( mediaWiki, jQuery ) );
diff --git a/ReplaceText.php b/ReplaceText.php
index 81c592a..62b12a3 100644
--- a/ReplaceText.php
+++ b/ReplaceText.php
@@ -34,14 +34,14 @@
        die();
 }
 
-define( 'REPLACE_TEXT_VERSION', '1.2' );
+define( 'REPLACE_TEXT_VERSION', '1.3' );
 
 // credits
 $wgExtensionCredits['specialpage'][] = [
        'path' => __FILE__,
        'name' => 'Replace Text',
        'version' => REPLACE_TEXT_VERSION,
-       'author' => [ 'Yaron Koren', 'Niklas Laxström', '...' ],
+       'author' => [ 'Yaron Koren', 'Niklas Laxström', '[https://hexmode.com/ 
Mark A. Hershberger]', '...' ],
        'url' => 'https://www.mediawiki.org/wiki/Extension:Replace_Text',
        'descriptionmsg' => 'replacetext-desc',
        'license-name' => 'GPL-2.0+'
@@ -49,19 +49,19 @@
 
 $wgMessagesDirs['ReplaceText'] = __DIR__ . '/i18n';
 $wgExtensionMessagesFiles['ReplaceTextAlias'] = __DIR__ . 
'/ReplaceText.alias.php';
-$wgJobClasses['replaceText'] = 'ReplaceTextJob';
+$wgJobClasses['replaceText'] = "MediaWiki\\Extension\\ReplaceText\\Job";
 
 // This extension uses its own permission type, 'replacetext'
 $wgAvailableRights[] = 'replacetext';
 $wgGroupPermissions['sysop']['replacetext'] = true;
 
-$wgHooks['AdminLinks'][] = 'ReplaceTextHooks::addToAdminLinks';
+$wgHooks['AdminLinks'][] = 
"MediaWiki\\Extension\\ReplaceText\\Hooks::addToAdminLinks";
 
-$wgSpecialPages['ReplaceText'] = 'SpecialReplaceText';
-$wgAutoloadClasses['ReplaceTextHooks'] = __DIR__ . '/ReplaceText.hooks.php';
-$wgAutoloadClasses['SpecialReplaceText'] = __DIR__ . '/SpecialReplaceText.php';
-$wgAutoloadClasses['ReplaceTextJob'] = __DIR__ . '/ReplaceTextJob.php';
-$wgAutoloadClasses['ReplaceTextSearch'] = __DIR__ . '/ReplaceTextSearch.php';
+$wgSpecialPages['ReplaceText'] = 
"MediaWiki\\Extension\\ReplaceText\\SpecialPage";
+$wgAutoloadClasses["ReplaceTextHooks"] = __DIR__ . '/ReplaceText.hooks.php';
+$wgAutoloadClasses["MediaWiki\\Extension\\ReplaceText\\SpecialPage"] = __DIR__ 
. '/SpecialReplaceText.php';
+$wgAutoloadClasses["MediaWiki\\Extension\\ReplaceText\\Job"] = __DIR__ . 
'/ReplaceTextJob.php';
+$wgAutoloadClasses["MediaWiki\\Extension\\ReplaceText\\Search"] = __DIR__ . 
'/ReplaceTextSearch.php';
 
 // Global variables
 $wgReplaceTextUser = null;
diff --git a/ReplaceTextJob.php b/ReplaceTextJob.php
index 548f57d..090d2a5 100644
--- a/ReplaceTextJob.php
+++ b/ReplaceTextJob.php
@@ -4,11 +4,47 @@
  * Background job to replace text in a given page
  * - based on /includes/RefreshLinksJob.php
  *
+ * Copyright (C) 2008-2017  Yaron Koren
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
  * @author Yaron Koren
  * @author Ankit Garg
  */
-class ReplaceTextJob extends Job {
-       function __construct( $title, $params = '', $id = 0 ) {
+
+namespace MediaWiki\\Extension\\ReplaceText;
+
+use Title;
+use User;
+use WatchAction;
+use WikiPage;
+use WikitextContent;
+
+class Job extends \Job {
+       protected $wikiPage;
+       protected $oldText;
+       protected $newText;
+
+       /**
+        * Ye ole constructor
+        * @param Title $title we're working on
+        * @param mixed $params for job
+        * @param int $id default
+        */
+       public function __construct( Title $title, array $params = [], $id = 0 
) {
                parent::__construct( 'replaceText', $title, $params, $id );
        }
 
@@ -16,7 +52,7 @@
         * Run a replaceText job
         * @return bool success
         */
-       function run() {
+       public function run() {
                wfProfileIn( __METHOD__ );
 
                if ( is_null( $this->title ) ) {
@@ -26,94 +62,150 @@
                }
 
                if ( array_key_exists( 'move_page', $this->params ) ) {
-                       global $wgUser;
-                       $actual_user = $wgUser;
-                       $wgUser = User::newFromId( $this->params['user_id'] );
-                       $cur_page_name = $this->title->getText();
-                       if ( $this->params['use_regex'] ) {
-                               $new_page_name = preg_replace(
-                                       "/" . $this->params['target_str'] . 
"/Uu", $this->params['replacement_str'], $cur_page_name
-                               );
-                       } else {
-                               $new_page_name =
-                                       str_replace( 
$this->params['target_str'], $this->params['replacement_str'], $cur_page_name );
-                       }
+                       $this->movePage();
+               } elseif ( $this->replaceText() === false ) {
+                       return false;
+               }
+               wfProfileOut( __METHOD__ );
+               return true;
+       }
 
-                       $new_title = Title::newFromText( $new_page_name, 
$this->title->getNamespace() );
-                       $reason = $this->params['edit_summary'];
-                       $create_redirect = $this->params['create_redirect'];
-                       $this->title->moveTo( $new_title, true, $reason, 
$create_redirect );
-                       if ( $this->params['watch_page'] ) {
-                               if ( class_exists( 'WatchAction' ) ) {
-                                       // Class was added in MW 1.19
-                                       WatchAction::doWatch( $new_title, 
$wgUser );
-                               } else {
-                                       Action::factory( 'watch', new WikiPage( 
$new_title ) )->execute();
-                               }
-                       }
-                       $wgUser = $actual_user;
+       /**
+        * ReplaceText job to move the page.
+        */
+       protected function movePage() {
+               global $wgUser;
+               $actual_user = $wgUser;
+               $wgUser = User::newFromId( $this->params['user_id'] );
+
+               $cur_page_name = $this->title->getText();
+               if ( $this->params['use_regex'] ) {
+                       $new_page_name = preg_replace(
+                               "/" . $this->params['target_str'] . "/Uu",
+                               $this->params['replacement_str'], $cur_page_name
+                       );
                } else {
-                       if ( $this->title->getContentModel() !== 
CONTENT_MODEL_WIKITEXT ) {
-                               $this->error = 'replaceText: Wiki page "' .
-                                       $this->title->getPrefixedDBkey() . '" 
does not hold regular wikitext.';
-                               wfProfileOut( __METHOD__ );
-                               return false;
-                       }
-                       $wikiPage = new WikiPage( $this->title );
-                       // Is this check necessary?
-                       if ( !$wikiPage ) {
-                               $this->error =
-                                       'replaceText: Wiki page not found for 
"' . $this->title->getPrefixedDBkey() . '."';
-                               wfProfileOut( __METHOD__ );
-                               return false;
-                       }
-                       $wikiPageContent = $wikiPage->getContent();
-                       if ( is_null( $wikiPageContent ) ) {
-                               $this->error =
-                                       'replaceText: No contents found for 
wiki page at "' . $this->title->getPrefixedDBkey() . '."';
-                               wfProfileOut( __METHOD__ );
-                               return false;
-                       }
-                       $article_text = $wikiPageContent->getNativeData();
+                       $new_page_name = str_replace(
+                               $this->params['target_str'],
+                               $this->params['replacement_str'],
+                               $cur_page_name
+                       );
+               }
 
+               $new_title = Title::newFromText(
+                       $new_page_name,
+                       $this->title->getNamespace()
+               );
+
+               $this->title->moveTo(
+                       $new_title, true, $this->params['edit_summary'],
+                       $this->params['create_redirect']
+               );
+
+               if ( $this->params['watch_page'] ) {
+                       WatchAction::doWatch( $new_title, $wgUser );
+               }
+
+               $wgUser = $actual_user;
+       }
+
+       /**
+        * General ReplaceText
+        * @return bool for the job
+        */
+       protected function replaceText() {
+               if ( $this->canReplaceText() ) {
                        wfProfileIn( __METHOD__ . '-replace' );
-                       $target_str = $this->params['target_str'];
-                       $replacement_str = $this->params['replacement_str'];
-                       $num_matches = 0;
-
-                       if ( $this->params['use_regex'] ) {
-                               $new_text =
-                                       preg_replace( '/' . $target_str . 
'/Uu', $replacement_str, $article_text, -1, $num_matches );
-                       } else {
-                               $new_text = str_replace( $target_str, 
$replacement_str, $article_text, $num_matches );
-                       }
-
-                       // If there's at least one replacement, modify the page,
-                       // using the passed-in edit summary.
-                       if ( $num_matches > 0 ) {
-                               // Change global $wgUser variable to the one
-                               // specified by the job only for the extent of
-                               // this replacement.
-                               global $wgUser;
-                               $actual_user = $wgUser;
-                               $wgUser = User::newFromId( 
$this->params['user_id'] );
-                               $edit_summary = $this->params['edit_summary'];
-                               $flags = EDIT_MINOR;
-                               if ( $wgUser->isAllowed( 'bot' ) ) {
-                                       $flags |= EDIT_FORCE_BOT;
-                               }
-                               if ( isset( $this->params['doEnotif'] ) &&
-                                        !$this->params['doEnotif'] ) {
-                                       $flags |= EDIT_SUPPRESS_RC;
-                                       # fixme log this action
-                               }
-                               $new_content = new WikitextContent( $new_text );
-                               $wikiPage->doEditContent( $new_content, 
$edit_summary, $flags );
-                               $wgUser = $actual_user;
+                       if ( $this->hasReplacements() ) {
+                               return $this->makeReplacments();
                        }
                        wfProfileOut( __METHOD__ . '-replace' );
                }
-               wfProfileOut( __METHOD__ );
+               return false;
+       }
+
+       /**
+        * Determine if we can even do this
+        * @return bool true if we can
+        */
+       protected function canReplaceText() {
+               if ( $this->title->getContentModel() !== CONTENT_MODEL_WIKITEXT 
) {
+                       $this->error = 'replaceText: Wiki page "' .
+                                                
$this->title->getPrefixedDBkey() .
+                                                '" does not hold regular 
wikitext.';
+                       wfProfileOut( __METHOD__ );
+                       return false;
+               }
+               $this->wikiPage = new WikiPage( $this->title );
+               // Is this check necessary?
+               if ( !$this->wikiPage ) {
+                       $this->error = 'replaceText: Wiki page not found for "'
+                                                . 
$this->title->getPrefixedDBkey() . '."';
+                       wfProfileOut( __METHOD__ );
+                       return false;
+               }
+               if ( is_null( $this->wikiPage->getContent() ) ) {
+                       $this->error = 'replaceText: No contents found for wiki 
page at "' .
+                                                
$this->title->getPrefixedDBkey() . '."';
+                       wfProfileOut( __METHOD__ );
+                       return false;
+               }
+               $this->oldText = $this->wikiPage->getContent()->getNativeData();
+
+               return true;
+       }
+
+       /**
+        * Determine if any replacments are needed.
+        * @return bool true if matches > 0
+        */
+       protected function hasReplacements() {
+               $target_str = $this->params['target_str'];
+               $replacement_str = $this->params['replacement_str'];
+               $num_matches = 0;
+
+               if ( $this->params['use_regex'] ) {
+                       $this->newText = preg_replace(
+                               '/' . $target_str . '/Uu', $replacement_str,
+                               $this->oldText, -1, $num_matches
+                       );
+               } else {
+                       $this->newText = str_replace(
+                               $target_str, $replacement_str,
+                               $this->oldText, $num_matches );
+               }
+
+               return $num_matches > 0;
+       }
+
+       /**
+        * Take care of the actual replacements.
+        * @return bool true for now, may find errors that should be false later
+        */
+       protected function makeReplacments() {
+               // Change global $wgUser variable to the one
+               // specified by the job only for the extent of
+               // this replacement.
+               global $wgUser;
+               $actual_user = $wgUser;
+
+               $wgUser = User::newFromId( $this->params['user_id'] );
+               $flags = EDIT_MINOR;
+               if ( $wgUser->isAllowed( 'bot' ) ) {
+                       $flags |= EDIT_FORCE_BOT;
+               }
+               if ( isset( $this->params['doEnotif'] ) &&
+                        !$this->params['doEnotif'] ) {
+                       $flags |= EDIT_SUPPRESS_RC;
+                       # fixme log this action
+               }
+
+               $new_content = new WikitextContent( $this->newText );
+               $this->wikiPage->doEditContent(
+                       $new_content, $this->params['edit_summary'], $flags
+               );
+
+               $wgUser = $actual_user;
                return true;
        }
 }
diff --git a/ReplaceTextSearch.js b/ReplaceTextSearch.js
new file mode 100644
index 0000000..67e4185
--- /dev/null
+++ b/ReplaceTextSearch.js
@@ -0,0 +1,43 @@
+/*!
+ * JavaScript for Special:ReplaceText
+ */
+( function ( mw, $ ) {
+       $( function () {
+               var $checkboxes, $headerLinks, updateHeaderLinks, searchWidget;
+
+               // Emulate HTML5 autofocus behavior in non HTML5 compliant 
browsers
+               if ( !( 'autofocus' in document.createElement( 'input' ) ) ) {
+                       $( 'input[autofocus]' ).eq( 0 ).focus();
+               }
+
+               // Create check all/none button
+               $checkboxes = $( '#powersearch input[id^=mw-search-ns]' );
+               $( '#mw-search-togglebox' ).append(
+                       $( '<label>' )
+                               .text( mw.msg( 'powersearch-togglelabel' ) )
+               ).append(
+                       $( '<input>' ).attr( 'type', 'button' )
+                               .attr( 'id', 'mw-search-toggleall' )
+                               .prop( 'value', mw.msg( 'powersearch-toggleall' 
) )
+                               .click( function () {
+                                       $checkboxes.prop( 'checked', true );
+                               } )
+               ).append(
+                       $( '<input>' ).attr( 'type', 'button' )
+                               .attr( 'id', 'mw-search-togglenone' )
+                               .prop( 'value', mw.msg( 
'powersearch-togglenone' ) )
+                               .click( function () {
+                                       $checkboxes.prop( 'checked', false );
+                               } )
+               );
+
+               // Bit stripped here since it was OOjs
+
+               // When saving settings, use the proper request method (POST 
instead of GET).
+               $( '#mw-search-powersearch-remember' ).change( function () {
+                       this.form.method = this.checked ? 'post' : 'get';
+               } ).trigger( 'change' );
+
+       } );
+
+}( mediaWiki, jQuery ) );
diff --git a/ReplaceTextSearch.php b/ReplaceTextSearch.php
index f9bf4a3..74657e0 100644
--- a/ReplaceTextSearch.php
+++ b/ReplaceTextSearch.php
@@ -1,6 +1,34 @@
 <?php
 
-class ReplaceTextSearch {
+/**
+ * Class to hold the logic for searches.
+ *
+ * Copyright (C) 2014-2017  NicheWork, LLC
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * @author Mark A. Hershberger <[email protected]>
+ */
+
+namespace MediaWiki\\Extension\\ReplaceText;
+
+use DatabasePostgres;
+use Title;
+
+class Search {
        public static function doSearchQuery(
                $search, $namespaces, $category, $prefix, $use_regex = false
        ) {
diff --git a/SpecialReplaceText.php b/SpecialReplaceText.php
index 46833a4..83e8445 100644
--- a/SpecialReplaceText.php
+++ b/SpecialReplaceText.php
@@ -1,6 +1,43 @@
 <?php
 
-class SpecialReplaceText extends SpecialPage {
+/**
+ * Special Page for ReplaceText
+ *
+ * Copyright (C) 2008-2017  Yaron Koren
+ * Copyright (C) 2017  NicheWork, LLC
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * @author Yaron Koren
+ * @author Mark A. Hershberger <[email protected]>
+ */
+
+namespace MediaWiki\\Extension\\ReplaceText;
+
+use Html;
+use JobQueueGroup;
+use Linker;
+use MWNamespace;
+use PermissionsError;
+use SearchEngine;
+use Title;
+use User;
+use XML;
+
+class SpecialPage extends \SpecialPage {
        private $target, $replacement, $use_regex,
                $category, $prefix, $edit_pages, $move_pages,
                $selected_namespaces, $doEnotif;
@@ -9,24 +46,40 @@
                parent::__construct( 'ReplaceText', 'replacetext' );
        }
 
+       /**
+        * Indicate that this page cannot operate on a read-only wiki
+        * @return bool
+        */
        public function doesWrites() {
                return true;
        }
 
-       function execute( $query ) {
+       /**
+        * Take care of the actual page load
+        * @param string $query any url stem (not used)
+        * @throws PermissionError
+        * @return mixed
+        */
+       public function execute( $query ) {
                if ( !$this->getUser()->isAllowed( 'replacetext' ) ) {
                        throw new PermissionsError( 'replacetext' );
                }
 
                $this->setHeaders();
                $out = $this->getOutput();
-               if ( !is_null( $out->getResourceLoader()->getModule( 
'mediawiki.special' ) ) ) {
+               if ( !is_null( $out->getResourceLoader()->getModule(
+                       'mediawiki.special'
+               ) ) ) {
                        $out->addModuleStyles( 'mediawiki.special' );
                }
-               $this->doSpecialReplaceText();
+               return $this->doSpecialReplaceText();
        }
 
-       function getSelectedNamespaces() {
+       /**
+        * Get the list of selected NS
+        * @return array
+        */
+       protected function getSelectedNamespaces() {
                $all_namespaces = SearchEngine::searchableNamespaces();
                $selected_namespaces = [];
                foreach ( $all_namespaces as $ns => $name ) {
@@ -37,9 +90,12 @@
                return $selected_namespaces;
        }
 
-       function doSpecialReplaceText() {
+       /**
+        * Take care of the form
+        * @return mixed
+        */
+       protected function doSpecialReplaceText() {
                wfProfileIn( __METHOD__ );
-               $out = $this->getOutput();
                $request = $this->getRequest();
 
                $this->target = $request->getText( 'target' );
@@ -58,220 +114,20 @@
                        return;
                }
 
+               // Don't even try if it isn't going to work
+               if ( $this->hasBadCategory() ) {
+                       $this->showBadCategory();
+                       return;
+               }
+
                if ( $request->getCheck( 'replace' ) ) {
-                       global $wgReplaceTextUser;
-
-                       $replacement_params = [];
-                       if ( $wgReplaceTextUser != null ) {
-                               $user = User::newFromName( $wgReplaceTextUser );
-                       } else {
-                               $user = $this->getUser();
-                       }
-                       $replacement_params['user_id'] = $user->getId();
-                       $replacement_params['target_str'] = $this->target;
-                       $replacement_params['replacement_str'] = 
$this->replacement;
-                       $replacement_params['use_regex'] = $this->use_regex;
-                       $replacement_params['edit_summary'] = $this->msg(
-                               'replacetext_editsummary',
-                               $this->target, $this->replacement
-                       )->inContentLanguage()->plain();
-                       $replacement_params['create_redirect'] = false;
-                       $replacement_params['watch_page'] = false;
-                       $replacement_params['doEnotif'] = $this->doEnotif;
-                       foreach ( $request->getValues() as $key => $value ) {
-                               if ( $key == 'create-redirect' && $value == '1' 
) {
-                                       $replacement_params['create_redirect'] 
= true;
-                               } elseif ( $key == 'watch-pages' && $value == 
'1' ) {
-                                       $replacement_params['watch_page'] = 
true;
-                               }
-                       }
-                       $jobs = [];
-                       foreach ( $request->getValues() as $key => $value ) {
-                               if ( $value == '1' && $key !== 'replace' && 
$key !== 'use_regex' ) {
-                                       if ( strpos( $key, 'move-' ) !== false 
) {
-                                               $title = Title::newFromID( 
substr( $key, 5 ) );
-                                               
$replacement_params['move_page'] = true;
-                                       } else {
-                                               $title = Title::newFromID( $key 
);
-                                       }
-                                       if ( $title !== null ) {
-                                               $jobs[] = new ReplaceTextJob( 
$title, $replacement_params );
-                                       }
-                               }
-                       }
-
-                       JobQueueGroup::singleton()->push( $jobs );
-
-                       $count = $this->getLanguage()->formatNum( count( $jobs 
) );
-                       $out->addWikiMsg(
-                               'replacetext_success',
-                               "<code><nowiki>{$this->target}</nowiki></code>",
-                               
"<code><nowiki>{$this->replacement}</nowiki></code>",
-                               $count
-                       );
-
-                       // Link back
-                       $out->addHTML(
-                               Linker::link( $this->getTitle(),
-                                       $this->msg( 'replacetext_return' 
)->escaped() )
-                       );
-
+                       $response = $this->doReplaceRequest();
                        wfProfileOut( __METHOD__ );
-                       return;
-               } elseif ( $request->getCheck( 'target' ) ) { // very long 
elseif, look for "end elseif"
-                       // first, check that at least one namespace has been
-                       // picked, and that either editing or moving pages
-                       // has been selected
-                       if ( count( $this->selected_namespaces ) == 0 ) {
-                               $this->showForm( 'replacetext_nonamespace' );
-                               wfProfileOut( __METHOD__ );
-                               return;
-                       }
-                       if ( ! $this->edit_pages && ! $this->move_pages ) {
-                               $this->showForm( 'replacetext_editormove' );
-                               wfProfileOut( __METHOD__ );
-                               return;
-                       }
-
-                       $titles_for_edit = [];
-                       $titles_for_move = [];
-                       $unmoveable_titles = [];
-
-                       // if user is replacing text within pages...
-                       if ( $this->edit_pages ) {
-                               $res = ReplaceTextSearch::doSearchQuery(
-                                       $this->target,
-                                       $this->selected_namespaces,
-                                       $this->category,
-                                       $this->prefix,
-                                       $this->use_regex
-                               );
-
-                               foreach ( $res as $row ) {
-                                       $title = Title::makeTitleSafe( 
$row->page_namespace, $row->page_title );
-                                       if ( $title == null ) {
-                                               continue;
-                                       }
-                                       $context = $this->extractContext( 
$row->old_text, $this->target, $this->use_regex );
-                                       $titles_for_edit[] = [ $title, $context 
];
-                               }
-                       }
-                       if ( $this->move_pages ) {
-                               $res = $this->getMatchingTitles(
-                                       $this->target,
-                                       $this->selected_namespaces,
-                                       $this->category,
-                                       $this->prefix,
-                                       $this->use_regex
-                               );
-
-                               foreach ( $res as $row ) {
-                                       $title = Title::makeTitleSafe( 
$row->page_namespace, $row->page_title );
-                                       if ( $title == null ) {
-                                               continue;
-                                       }
-                                       // See if this move can happen.
-                                       $cur_page_name = str_replace( '_', ' ', 
$row->page_title );
-
-                                       if ( $this->use_regex ) {
-                                               $new_page_name =
-                                                       preg_replace( "/" . 
$this->target . "/Uu", $this->replacement, $cur_page_name );
-                                       } else {
-                                               $new_page_name =
-                                                       str_replace( 
$this->target, $this->replacement, $cur_page_name );
-                                       }
-
-                                       $new_title = Title::makeTitleSafe( 
$row->page_namespace, $new_page_name );
-                                       $err = $title->isValidMoveOperation( 
$new_title );
-
-                                       if ( $title->userCan( 'move' ) && 
!is_array( $err ) ) {
-                                               $titles_for_move[] = $title;
-                                       } else {
-                                               $unmoveable_titles[] = $title;
-                                       }
-                               }
-                       }
-
-                       // If no results were found, check to see if a bad
-                       // category name was entered.
-                       if ( count( $titles_for_edit ) == 0 && count( 
$titles_for_move ) == 0 ) {
-                               $bad_cat_name = false;
-
-                               if ( !empty( $this->category ) ) {
-                                       $category_title = Title::makeTitleSafe( 
NS_CATEGORY, $this->category );
-                                       if ( !$category_title->exists() ) {
-                                               $bad_cat_name = true;
-                                       }
-                               }
-
-                               if ( $bad_cat_name ) {
-                                       $link = Linker::link( $category_title, 
htmlspecialchars( ucfirst( $this->category ) ) );
-                                       $out->addHTML(
-                                               $this->msg( 
'replacetext_nosuchcategory' )->rawParams( $link )->escaped()
-                                       );
-                               } else {
-                                       if ( $this->edit_pages ) {
-                                               $out->addWikiMsg(
-                                                       
'replacetext_noreplacement', "<code><nowiki>{$this->target}</nowiki></code>"
-                                               );
-                                       }
-
-                                       if ( $this->move_pages ) {
-                                               $out->addWikiMsg( 
'replacetext_nomove', "<code><nowiki>{$this->target}</nowiki></code>" );
-                                       }
-                               }
-                               // link back to starting form
-                               $out->addHTML(
-                                       '<p>' .
-                                       Linker::link(
-                                       $this->getTitle(),
-                                       $this->msg( 'replacetext_return' 
)->escaped() )
-                                       . '</p>'
-                               );
-                       } else {
-                               // Show a warning message if the replacement
-                               // string is either blank or found elsewhere on
-                               // the wiki (since undoing the replacement
-                               // would be difficult in either case).
-                               $warning_msg = null;
-
-                               if ( $this->replacement === '' ) {
-                                       $warning_msg = $this->msg( 
'replacetext_blankwarning' )->text();
-                               } elseif ( count( $titles_for_edit ) > 0 ) {
-                                       $res = ReplaceTextSearch::doSearchQuery(
-                                               $this->replacement,
-                                               $this->selected_namespaces,
-                                               $this->category,
-                                               $this->prefix,
-                                               $this->use_regex
-                                       );
-                                       $count = $res->numRows();
-                                       if ( $count > 0 ) {
-                                               $warning_msg = $this->msg( 
'replacetext_warning' )->numParams( $count )
-                                                       ->params( 
"<code><nowiki>{$this->replacement}</nowiki></code>" )->text();
-                                       }
-                               } elseif ( count( $titles_for_move ) > 0 ) {
-                                       $res = $this->getMatchingTitles(
-                                               $this->replacement,
-                                               $this->selected_namespaces,
-                                               $this->category,
-                                               $this->prefix, $this->use_regex
-                                       );
-                                       $count = $res->numRows();
-                                       if ( $count > 0 ) {
-                                               $warning_msg = $this->msg( 
'replacetext_warning' )->numParams( $count )
-                                                       ->params( 
$this->replacement )->text();
-                                       }
-                               }
-
-                               if ( ! is_null( $warning_msg ) ) {
-                                       $out->addWikiText( "<div 
class=\"errorbox\">$warning_msg</div><br clear=\"both\" />" );
-                               }
-
-                               $this->pageListForm( $titles_for_edit, 
$titles_for_move, $unmoveable_titles );
-                       }
+                       return $response;
+               } elseif ( $request->getCheck( 'target' ) ) {
+                       $response = $this->doTargetRequest();
                        wfProfileOut( __METHOD__ );
-                       return;
+                       return $response;
                }
 
                // If we're still here, show the starting form.
@@ -279,9 +135,402 @@
                wfProfileOut( __METHOD__ );
        }
 
-       function showForm( $warning_msg = null ) {
+       /**
+        * Examine the request for parameters & replacements
+        * @return array
+        */
+       protected function getReplacementParamsFromRequest() {
+               global $wgReplaceTextUser;
+
+               $request = $this->getRequest();
+               $user = $this->getUser();
+               if ( $wgReplaceTextUser != null ) {
+                       $user = User::newFromName( $wgReplaceTextUser );
+               }
+               $replacement_params['user_id'] = $user->getId();
+               $replacement_params['target_str'] = $this->target;
+               $replacement_params['replacement_str'] = $this->replacement;
+               $replacement_params['use_regex'] = $this->use_regex;
+               $replacement_params['edit_summary'] = $this->msg(
+                       'replacetext_editsummary',
+                       $this->target, $this->replacement
+               )->inContentLanguage()->plain();
+               $replacement_params['create_redirect'] = false;
+               $replacement_params['watch_page'] = false;
+               $replacement_params['doEnotif'] = $this->doEnotif;
+               foreach ( $request->getValues() as $key => $value ) {
+                       if ( $key == 'create-redirect' && $value == '1' ) {
+                               $replacement_params['create_redirect'] = true;
+                       } elseif ( $key == 'watch-pages' && $value == '1' ) {
+                               $replacement_params['watch_page'] = true;
+                       }
+               }
+               return $replacement_params;
+       }
+
+       /**
+        * See what ReplaceText jobs we can get from this request
+        * @param array $replacement_params the args we already have
+        * @return array
+        */
+       protected function getJobsFromRequest( $replacement_params ) {
+               $request = $this->getRequest();
+               $jobs = [];
+               foreach ( $request->getValues() as $key => $value ) {
+                       if (
+                               $value == '1'
+                               && $key !== 'replace'
+                               && $key !== 'use_regex'
+                       ) {
+                               if ( strpos( $key, 'move-' ) !== false ) {
+                                       $title = Title::newFromID( substr( 
$key, 5 ) );
+                                       $replacement_params['move_page'] = true;
+                               } else {
+                                       $title = Title::newFromID( $key );
+                               }
+                               if ( $title !== null ) {
+                                       $jobs[] = new Job( $title, 
$replacement_params );
+                               }
+                       }
+               }
+               return $jobs;
+       }
+
+       /**
+        * Handle requests for replacments
+        */
+       protected function doReplaceRequest() {
+               $request = $this->getRequest();
+
+               $jobs = $this->getJobsFromRequest(
+                       $this->getReplacementParamsFromRequest()
+               );
+
+               JobQueueGroup::singleton()->push( $jobs );
+
+               $count = $this->getLanguage()->formatNum( count( $jobs ) );
+               $out = $this->getOutput();
+               $out->addWikiMsg(
+                       'replacetext_success',
+                       "<code><nowiki>{$this->target}</nowiki></code>",
+                       "<code><nowiki>{$this->replacement}</nowiki></code>",
+                       $count
+               );
+
+               // Link back
+               $out->addHTML(
+                       Linker::link( $this->getTitle(),
+                                                 $this->msg( 
'replacetext_return' )->escaped() )
+               );
+
+               wfProfileOut( __METHOD__ );
+               return;
+       }
+
+       /**
+        * Transform the page name
+        * @param string $cur_page_name currently called
+        * @return string
+        */
+       protected function getNewPageName( $cur_page_name ) {
+               // See if this move can happen.
+               $cur_page_name = str_replace( '_', ' ', $cur_page_name );
+
+               if ( $this->use_regex ) {
+                       $new_page_name = preg_replace(
+                               "/" . $this->target . "/Uu",
+                               $this->replacement, $cur_page_name
+                       );
+               } else {
+                       $new_page_name = str_replace(
+                               $this->target, $this->replacement,
+                               $cur_page_name
+                       );
+               }
+               return $new_page_name;
+       }
+
+       /**
+        * Get the title we are editing
+        * @return array
+        */
+       protected function getTitlesForEdit() {
+               $titles_for_edit = [];
+
+               $res = Search::doSearchQuery(
+                       $this->target,
+                       $this->selected_namespaces,
+                       $this->category,
+                       $this->prefix,
+                       $this->use_regex
+               );
+
+               foreach ( $res as $row ) {
+                       $title = Title::makeTitleSafe(
+                               $row->page_namespace, $row->page_title
+                       );
+                       if ( $title == null ) {
+                               continue;
+                       }
+                       $context = $this->extractContext(
+                               $row->old_text, $this->target, $this->use_regex
+                       );
+                       $titles_for_edit[] = [ $title, $context ];
+               }
+
+               return $titles_for_edit;
+       }
+
+       /**
+        * Get the titles that we need to move
+        * @return array
+        */
+       protected function getTitlesForMove() {
+               $titles_for_move = [];
+               $unmoveable_titles = [];
+
+               $res = $this->getMatchingTitles(
+                       $this->target,
+                       $this->selected_namespaces,
+                       $this->category,
+                       $this->prefix,
+                       $this->use_regex
+               );
+
+               foreach ( $res as $row ) {
+                       $title = Title::makeTitleSafe(
+                               $row->page_namespace, $row->page_title
+                       );
+                       if ( $title == null ) {
+                               continue;
+                       }
+
+                       $new_title = Title::makeTitleSafe(
+                               $row->page_namespace, $this->getNewPageName( 
$row->page_title )
+                       );
+                       $err = $title->isValidMoveOperation( $new_title );
+
+                       if ( $title->userCan( 'move' ) && !is_array( $err ) ) {
+                               $titles_for_move[] = $title;
+                       } else {
+                               $unmoveable_titles[] = $title;
+                       }
+               }
+               return [ $titles_for_move, $unmoveable_titles ];
+       }
+
+       /**
+        * Get the titles we want to edit
+        * @return array
+        */
+       protected function getTitlesFromTargetRequest() {
+               $res = Search::doSearchQuery(
+                       $this->target,
+                       $this->selected_namespaces,
+                       $this->category,
+                       $this->prefix,
+                       $this->use_regex
+               );
+
+               $titles_for_edit = [];
+               foreach ( $res as $row ) {
+                       $title = Title::makeTitleSafe(
+                               $row->page_namespace, $row->page_title
+                       );
+                       if ( $title == null ) {
+                               continue;
+                       }
+                       $context = $this->extractContext(
+                               $row->old_text, $this->target, $this->use_regex
+                       );
+                       $titles_for_edit[] = [ $title, $context ];
+               }
+               return $titles_for_edit;
+       }
+
+       /**
+        * Get Title object for the chosen category.
+        * @return Title
+        */
+       protected function getCategoryTitle() {
+               return Title::makeTitleSafe( NS_CATEGORY, $this->category );
+       }
+
+       /**
+        * Make sure we have a usable category
+        * @return bool
+        */
+       protected function hasBadCategory() {
+               // If no results were found, check to see if a bad
+               // category name was entered.
+               if ( !empty( $this->category ) ) {
+                       if ( !$this->getCategoryTitle()->exists() ) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Show them the way back since they chose a bad category
+        */
+       protected function showBadCategory() {
+               $link = Linker::link(
+                       $this->getCategoryTitle(),
+                       htmlspecialchars( ucfirst( $this->category ) )
+               );
+               $this->getOutput()->addHTML(
+                       $this->msg( 'replacetext_nosuchcategory' )
+                       ->rawParams( $link )->escaped()
+               );
+               $this->showLinkBack();
+       }
+
+       /**
+        * Show a link back to the start
+        */
+       protected function showLinkBack() {
+               $this->getOutput()->addHTML(
+                       '<p>' .
+                       Linker::link(
+                               $this->getTitle(),
+                               $this->msg( 'replacetext_return' )->escaped() )
+                       . '</p>'
+               );
+       }
+
+       /**
+        * What to do if we don't match anything
+        */
+       protected function handleNoMatches() {
                $out = $this->getOutput();
 
+               if ( $this->hasBadCategory() ) {
+                       $this->showBadCategory();
+               } else {
+                       if ( $this->edit_pages ) {
+                               $out->addWikiMsg(
+                                       'replacetext_noreplacement',
+                                       
"<code><nowiki>{$this->target}</nowiki></code>"
+                               );
+                       }
+
+                       if ( $this->move_pages ) {
+                               $out->addWikiMsg(
+                                       'replacetext_nomove',
+                                       
"<code><nowiki>{$this->target}</nowiki></code>"
+                               );
+                       }
+                       $this->showLinkBack();
+               }
+       }
+
+       /**
+        * Give the list of pages, maybe get a warning message
+        * @param array $titles_for_edit list of titles to edit
+        * @param array $titles_for_move list of titles to move
+        * @return string
+        */
+       protected function maybeShowWarningMsg( $titles_for_edit, 
$titles_for_move ) {
+               $warning_msg = '';
+               if ( $this->replacement === '' ) {
+                       $warning_msg = $this->msg(
+                               'replacetext_blankwarning'
+                       )->text();
+               } elseif ( count( $titles_for_edit ) > 0 ) {
+                       $res = Search::doSearchQuery(
+                               $this->replacement,
+                               $this->selected_namespaces,
+                               $this->category,
+                               $this->prefix,
+                               $this->use_regex
+                       );
+                       $count = $res->numRows();
+                       if ( $count > 0 ) {
+                               $warning_msg = $this->msg( 
'replacetext_warning' )
+                                                        ->numParams( $count )
+                                                        ->params( 
'<code><nowiki>' .
+                                                                          
$this->replacement .
+                                                                          
'</nowiki></code>' )->text();
+                       }
+               } elseif ( count( $titles_for_move ) > 0 ) {
+                       $res = $this->getMatchingTitles(
+                               $this->replacement,
+                               $this->selected_namespaces,
+                               $this->category,
+                               $this->prefix, $this->use_regex
+                       );
+                       $count = $res->numRows();
+                       if ( $count > 0 ) {
+                               $warning_msg = $this->msg( 
'replacetext_warning' )
+                                                        ->numParams( $count )
+                                                        ->params( 
$this->replacement )->text();
+                       }
+               }
+               if ( $warning_msg ) {
+                       $this->getOutput()->addWikiText(
+                               '<div class="errorbox">' . $warning_msg .
+                               '</div><br clear="both" />'
+                       );
+               }
+       }
+
+       /**
+        * Handle pages we have targeted
+        */
+       protected function doTargetRequest() {
+               $out = $this->getOutput();
+               wfProfileIn( __METHOD__ );
+
+               // first, check that at least one namespace has been
+               // picked, and that either editing or moving pages
+               // has been selected
+               if ( count( $this->selected_namespaces ) == 0 ) {
+                       $this->showForm( 'replacetext_nonamespace' );
+                       wfProfileOut( __METHOD__ );
+                       return;
+               }
+               if ( ! $this->edit_pages && ! $this->move_pages ) {
+                       $this->showForm( 'replacetext_editormove' );
+                       wfProfileOut( __METHOD__ );
+                       return;
+               }
+
+               $titles_for_edit = $titles_for_move = $unmoveable_titles = [];
+
+               // if user is replacing text within pages...
+               if ( $this->edit_pages ) {
+                       $titles_for_edit = $this->getTitlesForEdit();
+               }
+               if ( $this->move_pages ) {
+                       list( $titles_for_move, $unmoveable_titles )
+                               = $this->getTitlesForMove();
+               }
+
+               if (
+                       count( $titles_for_edit ) == 0
+                       && count( $titles_for_move ) == 0
+               ) {
+                       $this->handleNoMatches();
+               } else {
+                       $this->maybeShowWarningMsg(
+                               $titles_for_edit, $titles_for_move
+                       );
+
+                       $this->pageListForm(
+                               $titles_for_edit, $titles_for_move, 
$unmoveable_titles
+                       );
+               }
+               wfProfileOut( __METHOD__ );
+               return;
+       }
+
+       /**
+        * Header of the form
+        * @param string $warning_msg to show
+        */
+       protected function showFormHeader( $warning_msg = null ) {
+               $out = $this->getOutput();
                $out->addHTML(
                        Xml::openElement(
                                'form',
@@ -302,7 +551,13 @@
                                $warning_msg
                        );
                }
+       }
 
+       /**
+        * The boxes to specify search/replace text.
+        */
+       protected function showFormSearchAndReplace() {
+               $out = $this->getOutput();
                $out->addHTML( '<table><tr><td style="vertical-align: top;">' );
                $out->addWikiMsg( 'replacetext_originaltext' );
                $out->addHTML( '</td><td>' );
@@ -310,13 +565,18 @@
                // normal 'width: 100%', which causes the textarea to get
                // zero width in IE
                $out->addHTML(
-                       Xml::textarea( 'target', $this->target, 100, 5, [ 
'style' => 'width: auto;' ] )
+                       Xml::textarea(
+                               'target', $this->target, 100, 5, [ 'style' => 
'width: auto;' ]
+                       )
                );
                $out->addHTML( '</td></tr><tr><td style="vertical-align: 
top;">' );
                $out->addWikiMsg( 'replacetext_replacementtext' );
                $out->addHTML( '</td><td>' );
                $out->addHTML(
-                       Xml::textarea( 'replacement', $this->replacement, 100, 
5, [ 'style' => 'width: auto;' ] )
+                       Xml::textarea(
+                               'replacement', $this->replacement, 100, 5,
+                               [ 'style' => 'width: auto;' ]
+                       )
                );
                $out->addHTML( '</td></tr></table>' );
                $out->addHTML( Xml::tags( 'p', null,
@@ -330,7 +590,13 @@
                                $this->msg( 'replacetext_regexdocu' )->text()
                        )
                );
+       }
 
+       /**
+        * The namespace picker
+        */
+       protected function showFormNamespaces() {
+               $out = $this->getOutput();
                // The interface is heavily based on the one in Special:Search.
                $namespaces = SearchEngine::searchableNamespaces();
                $tables = $this->namespaceTables( $namespaces );
@@ -343,9 +609,7 @@
                // search interface exists only in some skins, like Vector -
                // check for the presence of the 'powersearch-togglelabel'
                // message to see if we can use this functionality here.
-               if ( $this->msg( 'powersearch-togglelabel' )->isDisabled() ) {
-                       // do nothing
-               } else {
+               if ( !$this->msg( 'powersearch-togglelabel' )->isDisabled() ) {
                        $out->addHTML(
                                Html::element(
                                        'div',
@@ -357,41 +621,75 @@
                        Xml::element( 'div', [ 'class' => 'divider' ], '', 
false ) .
                        "$tables\n</fieldset>"
                );
+
+               // Add Javascript specific to Special:ReplaceText
+               $out->addModules( 'ext.ReplaceText.search' );
+       }
+
+       /**
+        * Our optional filters
+        */
+       protected function showFormOptionalFilters() {
+               $out = $this->getOutput();
+
                // @todo FIXME: raw html messages
-               $category_search_label = $this->msg( 
'replacetext_categorysearch' )->escaped();
-               $prefix_search_label = $this->msg( 'replacetext_prefixsearch' 
)->escaped();
+               $category_search_label
+                       = $this->msg( 'replacetext_categorysearch' )->escaped();
+               $prefix_search_label
+                       = $this->msg( 'replacetext_prefixsearch' )->escaped();
                $out->addHTML(
                        "<fieldset id=\"mw-searchoptions\">\n" .
-                       Xml::tags( 'h4', null, $this->msg( 
'replacetext_optionalfilters' )->parse() ) .
+                       Xml::tags(
+                               'h4', null,
+                               $this->msg( 'replacetext_optionalfilters' 
)->parse()
+                       ) .
                        Xml::element( 'div', [ 'class' => 'divider' ], '', 
false ) .
                        "<p>$category_search_label\n" .
-                       Xml::input( 'category', 20, $this->category, [ 'type' 
=> 'text' ] ) . '</p>' .
-                       "<p>$prefix_search_label\n" .
-                       Xml::input( 'prefix', 20, $this->prefix, [ 'type' => 
'text' ] ) . '</p>' .
-                       "</fieldset>\n" .
-                       "<p>\n" .
+                       Xml::input(
+                               'category', 20,
+                               $this->category, [ 'type' => 'text' ]
+                       ) . "</p><p>$prefix_search_label\n" .
+                       Xml::input(
+                               'prefix', 20,
+                               $this->prefix, [ 'type' => 'text' ]
+                       ) . "</p></fieldset>\n<p>\n" .
                        Xml::checkLabel(
-                               $this->msg( 'replacetext_editpages' )->text(), 
'edit_pages', 'edit_pages', true
-                       ) . '<br />' .
+                               $this->msg( 'replacetext_editpages' )->text(),
+                               'edit_pages', 'edit_pages', true
+                       ) . '<br>' .
                        Xml::checkLabel(
-                               $this->msg( 'replacetext_movepages' )->text(), 
'move_pages', 'move_pages'
-                       ) . '<br />' .
+                               $this->msg( 'replacetext_movepages' )->text(),
+                               'move_pages', 'move_pages'
+                       ) . '<br>' .
                        Xml::checkLabel(
-                               $this->msg( 'replacetext_enotif' )->text(), 
'doEnotif', 'doEnotif', true
+                               $this->msg( 'replacetext_enotif' )->text(),
+                               'doEnotif', 'doEnotif', true
                        ) .
                        "</p>\n" .
                        Xml::submitButton( $this->msg( 'replacetext_continue' 
)->text() ) .
                        Xml::closeElement( 'form' )
                );
-               // Add Javascript specific to Special:Search
-               $out->addModules( 'mediawiki.special.search' );
+       }
+
+       /**
+        * Show the ReplaceText form
+        * @param string $warning_msg to show, maybe
+        */
+       protected function showForm( $warning_msg = null ) {
+               $this->showFormHeader( $warning_msg );
+               $this->showFormSearchAndReplace();
+               $this->showFormNamespaces();
+               $this->showFormOptionalFilters();
        }
 
        /**
         * Copied almost exactly from MediaWiki's SpecialSearch class, i.e.
         * the search page
+        * @param array $namespaces to list
+        * @param int $rowsPerTable to show
+        * @return string
         */
-       function namespaceTables( $namespaces, $rowsPerTable = 3 ) {
+       protected function namespaceTables( $namespaces, $rowsPerTable = 3 ) {
                global $wgContLang;
                // Group namespaces into rows according to subject.
                // Try not to make too many assumptions about namespace 
numbering.
@@ -406,17 +704,21 @@
                        if ( '' == $name ) {
                                $name = $this->msg( 'blanknamespace' )->text();
                        }
-                       $rows[$subj] .= Xml::openElement( 'td', [ 'style' => 
'white-space: nowrap' ] ) .
-                               Xml::checkLabel( $name, "ns{$ns}", 
"mw-search-ns{$ns}", in_array( $ns, $namespaces ) ) .
-                               Xml::closeElement( 'td' ) . "\n";
+                       $rows[$subj] .= Xml::openElement(
+                               'td', [ 'style' => 'white-space: nowrap' ]
+                       ) . Xml::checkLabel(
+                               $name, "ns{$ns}", "mw-search-ns{$ns}",
+                               in_array( $ns, $namespaces )
+                       ) . Xml::closeElement( 'td' ) . "\n";
                }
                $rows = array_values( $rows );
                $numRows = count( $rows );
                // Lay out namespaces in multiple floating two-column tables so 
they'll
                // be arranged nicely while still accommodating different 
screen widths
                // Float to the right on RTL wikis
-               $tableStyle = $wgContLang->isRTL() ?
-                       'float: right; margin: 0 0 0em 1em' : 'float: left; 
margin: 0 1em 0em 0';
+               $tableStyle = $wgContLang->isRTL()
+                                       ? 'float: right; margin: 0 0 0em 1em'
+                                       : 'float: left; margin: 0 1em 0em 0';
                // Build the final HTML table...
                for ( $i = 0; $i < $numRows; $i += $rowsPerTable ) {
                        $tables .= Xml::openElement( 'table', [ 'style' => 
$tableStyle ] );
@@ -428,9 +730,78 @@
                return $tables;
        }
 
-       function pageListForm( $titles_for_edit, $titles_for_move, 
$unmoveable_titles ) {
-               global $wgLang, $wgScriptPath;
+       /**
+        * Show the titles that should be edited
+        * @param array $titles_for_edit list of titles to show
+        */
+       protected function showTitlesForEdit( $titles_for_edit ) {
+               global $wgLang;
+               $out = $this->getOutput();
 
+               if ( count( $titles_for_edit ) > 0 ) {
+                       $out->addWikiMsg(
+                               'replacetext_choosepagesforedit',
+                               "<code><nowiki>{$this->target}</nowiki></code>",
+                               
"<code><nowiki>{$this->replacement}</nowiki></code>",
+                               $wgLang->formatNum( count( $titles_for_edit ) )
+                       );
+
+                       foreach ( $titles_for_edit as $title_and_context ) {
+                               /**
+                                * @var $title Title
+                                */
+                               list( $title, $context ) = $title_and_context;
+                               $out->addHTML(
+                                       Xml::check( $title->getArticleID(), 
true ) .
+                                       Linker::link( $title ) .
+                                       " - <small>$context</small><br />\n"
+                               );
+                       }
+                       $out->addHTML( '<br />' );
+               }
+       }
+
+       /**
+        * Show the titles slated to be moved
+        * @param array $titles_for_move the titles
+        */
+       protected function showTitlesForMove( $titles_for_move ) {
+               global $wgLang;
+               $out = $this->getOutput();
+
+               if ( count( $titles_for_move ) > 0 ) {
+                       $out->addWikiMsg(
+                               'replacetext_choosepagesformove',
+                               $this->target, $this->replacement,
+                               $wgLang->formatNum( count( $titles_for_move ) )
+                       );
+                       foreach ( $titles_for_move as $title ) {
+                               $out->addHTML(
+                                       Xml::check( 'move-' . 
$title->getArticleID(), true ) .
+                                       Linker::link( $title ) . "<br />\n"
+                               );
+                       }
+                       $out->addHTML( '<br />' );
+                       $out->addWikiMsg( 'replacetext_formovedpages' );
+                       $out->addHTML(
+                               Xml::checkLabel(
+                                       $this->msg( 
'replacetext_savemovedpages' )->text(),
+                                       'create-redirect', 'create-redirect', 
true ) . "<br>" .
+                               Xml::checkLabel(
+                                       $this->msg( 
'replacetext_watchmovedpages' )->text(),
+                                       'watch-pages', 'watch-pages', false
+                               ) . '<br>' .
+                               Xml::checkLabel(
+                                       $this->msg( 'replacetext_doenotif' 
)->text(),
+                                       'doEnotif', 'doEnotif', true ) . '<br>'
+                       );
+               }
+       }
+
+       /**
+        * Show the page list form's header
+        */
+       protected function showPageListHeader() {
                $out = $this->getOutput();
 
                $formOpts = [
@@ -454,64 +825,28 @@
                        $out->addHTML( Html::hidden( 'ns' . $ns, 1 ) );
                }
 
-               $out->addScriptFile( 
"$wgScriptPath/extensions/ReplaceText/ReplaceText.js" );
+               $out->addModules( 'ext.ReplaceText.form' );
+       }
 
-               if ( count( $titles_for_edit ) > 0 ) {
-                       $out->addWikiMsg(
-                               'replacetext_choosepagesforedit',
-                               "<code><nowiki>{$this->target}</nowiki></code>",
-                               
"<code><nowiki>{$this->replacement}</nowiki></code>",
-                               $wgLang->formatNum( count( $titles_for_edit ) )
-                       );
-
-                       foreach ( $titles_for_edit as $title_and_context ) {
-                               /**
-                                * @var $title Title
-                                */
-                               list( $title, $context ) = $title_and_context;
-                               $out->addHTML(
-                                       Xml::check( $title->getArticleID(), 
true ) .
-                                       Linker::link( $title ) . " - 
<small>$context</small><br />\n"
-                               );
-                       }
-                       $out->addHTML( '<br />' );
-               }
-
-               if ( count( $titles_for_move ) > 0 ) {
-                       $out->addWikiMsg(
-                               'replacetext_choosepagesformove',
-                               $this->target, $this->replacement, 
$wgLang->formatNum( count( $titles_for_move ) )
-                       );
-                       foreach ( $titles_for_move as $title ) {
-                               $out->addHTML(
-                                       Xml::check( 'move-' . 
$title->getArticleID(), true ) .
-                                       Linker::link( $title ) . "<br />\n"
-                               );
-                       }
-                       $out->addHTML( '<br />' );
-                       $out->addWikiMsg( 'replacetext_formovedpages' );
-                       $out->addHTML(
-                               Xml::checkLabel(
-                                       $this->msg( 
'replacetext_savemovedpages' )->text(),
-                                               'create-redirect', 
'create-redirect', true ) . "<br />\n" .
-                               Xml::checkLabel(
-                                       $this->msg( 
'replacetext_watchmovedpages' )->text(),
-                                       'watch-pages', 'watch-pages', false ) . 
'<br />' .
-                               Xml::checkLabel(
-                                       $this->msg( 'replacetext_doenotif' 
)->text(),
-                                       'doEnotif', 'doEnotif', true ) . '<br 
/>'
-                       );
-                       $out->addHTML( '<br />' );
-               }
-
+       /**
+        * Show the submit button
+        * @param array $titles_for_edit list of titles to edit
+        * @param array $titles_for_move list of titles to move
+        * @param int $limit if there are more show the invert selection
+        */
+       protected function showPageListFooter(
+               $titles_for_edit, $titles_for_move, $limit
+       ) {
+               $out = $this->getOutput();
                $out->addHTML(
                        "<br />\n" .
-                       Xml::submitButton( $this->msg( 'replacetext_replace' 
)->text() ) . "\n"
+                       Xml::submitButton(
+                               $this->msg( 'replacetext_replace' )->text()
+                       ) . "\n"
                );
-
                // Only show "invert selections" link if there are more than
                // five pages.
-               if ( count( $titles_for_edit ) + count( $titles_for_move ) > 5 
) {
+               if ( count( $titles_for_edit ) + count( $titles_for_move ) > 
$limit ) {
                        $buttonOpts = [
                                'type' => 'button',
                                'value' => $this->msg( 
'replacetext_invertselections' )->text(),
@@ -524,9 +859,21 @@
                }
 
                $out->addHTML( '</form>' );
+       }
+
+       /**
+        * Show the unmovable titles, if any
+        * @param array $unmoveable_titles list of titles
+        */
+       protected function showUnmoveableTitles( $unmoveable_titles ) {
+               global $wgLang;
+               $out = $this->getOutput();
 
                if ( count( $unmoveable_titles ) > 0 ) {
-                       $out->addWikiMsg( 'replacetext_cannotmove', 
$wgLang->formatNum( count( $unmoveable_titles ) ) );
+                       $out->addWikiMsg(
+                               'replacetext_cannotmove',
+                               $wgLang->formatNum( count( $unmoveable_titles ) 
)
+                       );
                        $text = "<ul>\n";
                        foreach ( $unmoveable_titles as $title ) {
                                $text .= "<li>" . Linker::link( $title ) . "<br 
/>\n";
@@ -537,30 +884,32 @@
        }
 
        /**
-        * Extract context and highlights search text
-        *
-        * @todo The bolding needs to be fixed for regular expressions.
+        * Get the form for the page lists given
+        * @param array $titles_for_edit list of titles to edit
+        * @param array $titles_for_move list of titles to move
+        * @param array $unmoveable_titles titles that can't be moved
         */
-       function extractContext( $text, $target, $use_regex = false ) {
-               global $wgLang;
+       protected function pageListForm(
+               $titles_for_edit, $titles_for_move, $unmoveable_titles
+       ) {
+               $this->showPageListHeader();
 
-               wfProfileIn( __METHOD__ );
+               $this->showTitlesForEdit( $titles_for_edit );
+               $this->showTitlesForMove( $titles_for_move );
+               $this->showPageListFooter( $titles_for_edit, $titles_for_move, 
5 );
+               $this->showUnmoveableTitles( $unmoveable_titles );
+       }
+
+       /**
+        * Get the cuts of text
+        * @param array $poss list of positions
+        * @param string $target to match on
+        * @return array
+        */
+       protected function getCuts( $poss, $target ) {
+               $cuts = [];
                $cw = $this->getUser()->getOption( 'contextchars', 40 );
 
-               // Get all indexes
-               if ( $use_regex ) {
-                       preg_match_all( "/$target/Uu", $text, $matches, 
PREG_OFFSET_CAPTURE );
-               } else {
-                       $targetq = preg_quote( $target, '/' );
-                       preg_match_all( "/$targetq/", $text, $matches, 
PREG_OFFSET_CAPTURE );
-               }
-
-               $poss = [];
-               foreach ( $matches[0] as $_ ) {
-                       $poss[] = $_[1];
-               }
-
-               $cuts = [];
                // @codingStandardsIgnoreStart
                for ( $i = 0; $i < count( $poss ); $i++ ) {
                // @codingStandardsIgnoreEnd
@@ -573,36 +922,101 @@
                                        $len += $poss[$i + 1] - $poss[$i];
                                        $i++;
                                } else {
-                                       break; // Can't merge, exit the inner 
loop
+                                       // Can't merge, exit the inner loop
+                                       break;
                                }
                        }
                        $cuts[] = [ $index, $len ];
                }
+               return $cuts;
+       }
+
+       /**
+        * Extract context and highlights search text
+        * @param string $text string to match
+        * @param string $target string to perform match on
+        * @param bool $use_regex treat text as regex or no
+        * @return string
+        * @todo The bolding needs to be fixed for regular expressions.
+        */
+       protected function extractContext( $text, $target, $use_regex = false ) 
{
+               wfProfileIn( __METHOD__ );
+
+               // Get all indexes
+               if ( $use_regex ) {
+                       preg_match_all(
+                               "/$target/Uu", $text, $matches, 
PREG_OFFSET_CAPTURE
+                       );
+               } else {
+                       $targetq = preg_quote( $target, '/' );
+                       preg_match_all(
+                               "/$targetq/", $text, $matches, 
PREG_OFFSET_CAPTURE
+                       );
+               }
+
+               $poss = [];
+               foreach ( $matches[0] as $_ ) {
+                       $poss[] = $_[1];
+               }
+
+               $cuts = $this->getCuts( $poss, $target );
+
+               $context = $this->getCutContext( $cuts, $text, $target, 
$use_regex );
+
+               wfProfileOut( __METHOD__ );
+               return $context;
+       }
+
+       /**
+        * Get the context of the cut
+        * @param array $cuts list of cuts
+        * @param string $text matching string
+        * @param string $target string to perform match on
+        * @param bool $use_regex treat text as regex or no
+        * @return string
+        */
+       protected function getCutContext( $cuts, $text, $target, $use_regex ) {
+               global $wgLang;
+               $cw = $this->getUser()->getOption( 'contextchars', 40 );
 
                $context = '';
                foreach ( $cuts as $_ ) {
                        list( $index, $len, ) = $_;
                        $context .= $this->convertWhiteSpaceToHTML(
-                               $wgLang->truncate( substr( $text, 0, $index ), 
- $cw, '...', false )
+                               $wgLang->truncate(
+                                       substr( $text, 0, $index ), - $cw, 
'...', false
+                               )
                        );
-                       $snippet = $this->convertWhiteSpaceToHTML( substr( 
$text, $index, $len ) );
+                       $snippet = $this->convertWhiteSpaceToHTML(
+                               substr( $text, $index, $len )
+                       );
                        if ( $use_regex ) {
                                $targetStr = "/$target/Uu";
                        } else {
-                               $targetq = preg_quote( 
$this->convertWhiteSpaceToHTML( $target ), '/' );
+                               $targetq = preg_quote(
+                                       $this->convertWhiteSpaceToHTML( $target 
), '/'
+                               );
                                $targetStr = "/$targetq/i";
                        }
-                       $context .= preg_replace( $targetStr, '<span 
class="searchmatch">\0</span>', $snippet );
-
-                       $context .= $this->convertWhiteSpaceToHTML(
-                               $wgLang->truncate( substr( $text, $index + $len 
), $cw, '...', false )
+                       $context .= preg_replace(
+                               $targetStr, '<span 
class="rt-searchmatch">\0</span>', $snippet
                        );
+
+                       $context .= $this->convertWhiteSpaceToHTML( 
$wgLang->truncate(
+                               substr( $text, $index + $len ), $cw, '...', 
false
+                       ) );
                }
-               wfProfileOut( __METHOD__ );
+               $this->getOutput()->addModules( 'ext.ReplaceText.results' );
+
                return $context;
        }
 
-       private function convertWhiteSpaceToHTML( $msg ) {
+       /**
+        * convert the w/s to something htmlish
+        * @param string $msg to convert
+        * @return string
+        */
+       protected function convertWhiteSpaceToHTML( $msg ) {
                $msg = htmlspecialchars( $msg );
                $msg = preg_replace( '/^ /m', '&#160; ', $msg );
                $msg = preg_replace( '/ $/m', ' &#160;', $msg );
@@ -611,7 +1025,18 @@
                return $msg;
        }
 
-       function getMatchingTitles( $str, $namespaces, $category, $prefix, 
$use_regex = false ) {
+       /**
+        * Get a list of matching titles
+        * @param string $str what to match
+        * @param array $namespaces where to look
+        * @param string $category in which category
+        * @param string $prefix starts with
+        * @param bool $use_regex match uses regular expressions
+        * @return ResultWrapper
+        */
+       protected function getMatchingTitles(
+               $str, array $namespaces, $category, $prefix, $use_regex = false
+       ) {
                $dbr = wfGetDB( DB_REPLICA );
 
                $tables = [ 'page' ];
@@ -619,24 +1044,31 @@
 
                $str = str_replace( ' ', '_', $str );
                if ( $use_regex ) {
-                       $comparisonCond = ReplaceTextSearch::regexCond( $dbr, 
'page_title', $str );
+                       $comparisonCond = Search::regexCond(
+                               $dbr, 'page_title', $str
+                       );
                } else {
                        $any = $dbr->anyString();
-                       $comparisonCond = 'page_title ' . $dbr->buildLike( 
$any, $str, $any );
+                       $comparisonCond = 'page_title ' .
+                                                       $dbr->buildLike( $any, 
$str, $any );
                }
                $conds = [
                        $comparisonCond,
                        'page_namespace' => $namespaces,
                ];
 
-               ReplaceTextSearch::categoryCondition( $category, $tables, 
$conds );
-               ReplaceTextSearch::prefixCondition( $prefix, $conds );
+               Search::categoryCondition( $category, $tables, $conds );
+               Search::prefixCondition( $prefix, $conds );
                $sort = [ 'ORDER BY' => 'page_namespace, page_title' ];
 
                return $dbr->select( $tables, $vars, $conds, __METHOD__, $sort 
);
        }
 
-       protected function getGroupName() {
+       /**
+        * Where we want this special page to show up
+        * @return string
+        */
+       public function getGroupName() {
                return 'wiki';
        }
 }
diff --git a/extension.json b/extension.json
index b239331..a4f4ccf 100644
--- a/extension.json
+++ b/extension.json
@@ -1,9 +1,10 @@
 {
        "name": "Replace Text",
-       "version": "1.2",
+       "version": "1.3",
        "author": [
                "Yaron Koren",
                "Niklas Laxström",
+               "[https://hexmode.com/ Mark A. Hershberger]",
                "..."
        ],
        "url": "https://www.mediawiki.org/wiki/Extension:Replace_Text";,
@@ -19,10 +20,10 @@
                "replacetext"
        ],
        "SpecialPages": {
-               "ReplaceText": "SpecialReplaceText"
+               "ReplaceText": "MediaWiki\\Extension\\ReplaceText\\SpecialPage"
        },
        "JobClasses": {
-               "replaceText": "ReplaceTextJob"
+               "replaceText": "MediaWiki\\Extension\\ReplaceText\\Job"
        },
        "MessagesDirs": {
                "ReplaceText": [
@@ -33,18 +34,44 @@
                "ReplaceTextAlias": "ReplaceText.alias.php"
        },
        "AutoloadClasses": {
-               "ReplaceTextHooks": "ReplaceText.hooks.php",
-               "SpecialReplaceText": "SpecialReplaceText.php",
-               "ReplaceTextJob": "ReplaceTextJob.php",
-               "ReplaceTextSearch": "ReplaceTextSearch.php"
+               "MediaWiki\\Extension\\ReplaceText\\Hook": 
"ReplaceText.hooks.php",
+               "MediaWiki\\Extension\\ReplaceText\\SpecialPage": 
"SpecialReplaceText.php",
+               "MediaWiki\\Extension\\ReplaceText\\Job": "ReplaceTextJob.php",
+               "MediaWiki\\Extension\\ReplaceText\\Search": 
"ReplaceTextSearch.php"
        },
        "Hooks": {
                "AdminLinks": [
-                       "ReplaceTextHooks::addToAdminLinks"
+                       
"MediaWiki\\Extension\\ReplaceText\\Hook::addToAdminLinks"
                ]
        },
        "config": {
                "ReplaceTextUser": null
        },
+       "ResourceModules": {
+               "ext.ReplaceText.results": {
+                       "styles": "ReplaceText.css"
+               },
+               "ext.ReplaceText.form": {
+                       "scripts": "ReplaceText.js",
+                       "dependencies": [
+                               "mediawiki.special"
+                       ]
+               },
+               "ext.ReplaceText.search": {
+                       "scripts": "ReplaceTextSearch.js",
+                       "dependencies": [
+                               "oojs-ui-core"
+                       ],
+                       "messages": [
+                               "powersearch-togglelabel",
+                               "powersearch-toggleall",
+                               "powersearch-togglenone"
+                       ]
+               }
+       },
+       "ResourceFileModulePaths": {
+               "localBasePath": "",
+               "remoteExtPath": "ReplaceText"
+       },
        "manifest_version": 1
 }
diff --git a/replaceAll.php b/replaceAll.php
index 5f91d70..a93c52a 100755
--- a/replaceAll.php
+++ b/replaceAll.php
@@ -4,7 +4,7 @@
  * Insert jobs into the job queue to replace text bits.
  * Or execute immediately... your choice.
  *
- * Copyright © 2014 Mark A. Hershberger <[email protected]>
+ * Copyright (c) 2014  NicheWork, LLC
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,16 +31,26 @@
  * @link     https://www.mediawiki.org/wiki/Extension:Replace_Text
  *
  */
-// @codingStandardsIgnoreStart
-$IP = "../..";
+
+namespace MediaWiki\\Extension\\ReplaceText;
+
+use Maintenance;
+use MWException;
+use Title;
+use User;
+
+$IP = __DIR__ . '/../../';
 if ( !is_readable( "$IP/maintenance/Maintenance.php" ) ) {
        $IP = getenv( "MW_INSTALL_PATH" );
        if ( $IP === false ) {
-               die( "MW_INSTALL_PATH needs to be set to your MediaWiki 
installation." );
+               if ( !is_readable( getcwd() . "/maintenance/Maintenance.php" ) 
) {
+                       die( "MW_INSTALL_PATH needs to be set to your MediaWiki 
installation." );
+               }
+               $IP = getcwd();
        }
 }
-require_once ( "$IP/maintenance/Maintenance.php" );
-// @codingStandardsIgnoreEnd
+
+require_once "$IP/maintenance/Maintenance.php";
 
 /**
  * Maintenance script that generates a plaintext link dump.
@@ -49,7 +59,7 @@
  * @SuppressWarnings(StaticAccess)
  * @SuppressWarnings(LongVariable)
  */
-class ReplaceText extends Maintenance {
+class ReplaceAll extends Maintenance {
        protected $user;
        protected $target;
        protected $replacement;
@@ -301,7 +311,7 @@
                                'doEnotif'        => $this->doEnotif
                        ];
                        echo "Replacing on $title... ";
-                       $job = new ReplaceTextJob( $title, $param, 0 );
+                       $job = new Job( $title, $param, 0 );
                        if ( $job->run() !== true ) {
                                $this->error( "Trouble on the page '$title'." );
                        }
@@ -365,7 +375,7 @@
                                        }
                                        echo "\n";
                                }
-                               $res = ReplaceTextSearch::doSearchQuery( 
$target,
+                               $res = Search::doSearchQuery( $target,
                                        $this->namespaces, $this->category, 
$this->prefix, $useRegex );
 
                                if ( $res->numRows() === 0 ) {
@@ -398,5 +408,5 @@
        }
 }
 
-$maintClass = "ReplaceText";
+$maintClass = "ReplaceText\\ReplaceAll";
 require_once RUN_MAINTENANCE_IF_MAIN;

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I251188efa2fc1fbf0563b0e1f792a912d077d8c9
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/ReplaceText
Gerrit-Branch: master
Gerrit-Owner: MarkAHershberger <[email protected]>

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

Reply via email to