User:Ponor/wAwB
From Wikipedia, the free encyclopedia
wAwB[note 1] is a powerful browser-based tool for automated editing on MediaWiki sites using find & replace rules, regular expressions, and user-defined JavaScript functions. Administrators can use the tool to move, delete, and protect pages.
(24 days ago)
User script wAwB in action. | |
| Author | User:Ponor |
|---|---|
| First released | February 2, 2026 |
| Updated | February 26, 2026 (24 days ago) |
| Source | User:Ponor/wAwB.js |
Inspired by the desktop AutoWikiBrowser application, wAwB builds on the idea of the earlier JavaScript Wiki Browser and extends its functionality in several ways. It provides a modern user interface with a full-fledged CodeMirror text editor, configurable protection or targeting of selected portions of wikitext, and support for user-defined external JavaScript function libraries as well as shared and local typo-correction rules. The tool runs entirely in a web browser on a dedicated page and does not require the installation of executable software.
Permissions & safety
wAwB makes the same types of edits as AWB, so please abide by WP:AWBRULES.
Access control
wAwB checks your permissions automatically on startup.
- Administrators always get full access to the tool.
- CheckPage: The script looks for a JSON configuration page at Project:AutoWikiBrowser/CheckPageJSON.
- If your username is in
enabledusers: You have full access to manual saving. - If your username is in
enabledbotsAND you belong to the 'bot' user group: You have access to Bot mode (automated saving).
- If your username is in
- Fallback – no CheckPage: If the JSON page does not exist on the wiki:
- Users with < 500 edits cannot save.
- Users with > 500 edits can save, but are rate-limited to one edit every 30 seconds.
- Bot mode is disabled for everyone.
Technical safety
Critical processing tasks (such as executing your Find/Replace rules and custom scripts) are run inside a Web worker. This ensures that complex operations do not freeze your browser interface. To prevent infinite loops or crashes, the script enforces a strict 5-second timeout. If your custom script or regex takes longer than 5 seconds to process a single page, the operation will be aborted for safety. This limit can be changed by setting the global variable window.wa_timeout = 5000 to some other value (in milliseconds) before the invocation of the script.
Installation
To install wAwB, add the following line to your common.js file on a local wiki, or to global.js on metawiki:
// Automated editing tool [[:en:User:Ponor/wAwB]]
mw.loader.load('https://en.wikipedia.org/wiki/User:Ponor/wAwB.js?action=raw&ctype=text/javascript');
Once the lightweight portlet script is installed, a link labeled Edit in wAwB will appear in the sidebar Toolbox on every page. Clicking this link opens the wAwB interface in a blank page environment at Special:Blankpage/wAwB.
The edits will be tagged if your wiki's administrators have created a wAwB tag, i. e. if there is a page such as MediaWiki:Tag-wAwB; otherwise, (wAwB) will be added to your edit summary.
Configuration
A few global variables defined before the mw.loader invocation can change the script's behavior. Here are their default values:
// 5000 millisecond timeout for replacement rules and scripts
window.wa_timeout = 5000;
// fetch no more than ten thousand titles
window.wa_fetchLimit = 10000;
// documentation URL
window.wa_docUrl = "https://en.wikipedia.org/wiki/User:Ponor/wAwB";
// portlet link and script window titles
window.wa_editIn = "Edit in wAwB";
// portlet tooltip
window.wa_toolTip = "Automated editing gadget";
Typical workflow

Ctrl + Shift + , to open its options menu.- Load the tool: Run the script. The interface appears, splitting the screen into a left panel (Controls) and right panel (a full-fledged CodeMirror editor and Preview/Diff).
- Get sources: Open the Source tab to generate a list of pages (e.g., from a Category or "What links here").
- Define rules: Open the Rules tab to set up your Find & Replace logic.
- Save project: (optional): You can save your current configuration to your computer to resume later.
- Start processing: Open the Processing tab, type in your edit summary, and click the Power (Start) button.
- Review & save:
- The tool loads the first page.
- It applies your rules.
- It shows a diff of the changes (click on any line to jump to that line in the editor below), or page preview
- You click Save to apply the edit and move to the next page, or Skip to ignore the changes.
Interface guide
Toolbar (Project management)
Located at the top of the left panel, these buttons allow you to persist your work.
Save project Downloads a .jsonfile to your computer containing your entire current state:- All defined Find/Replace rules.
- All protection settings (Templates, Refs, etc.).
- Skip logic and content filters.
- Custom pre/post scripts.
- The current page list and the edit summary.
Load project Restores a previously saved configuration file.
Source (Getting pages)
This panel allows you to generate the list of pages you want to edit.
- Mode: Select how to find pages:
- Category: Enter a category name (e.g., "Chemistry"). Options allow including subcategories or files. API docs
- Pages linking to...: Finds backlinks. API docs
- Links on page...:
- Pages with prefix...: All pages starting with a specific string. API docs
- Watchlist: Loads your entire watchlist. API docs
- Wiki search: Use MediaWiki search syntax. CirrusSearch docs · API docs
- User contributions: Titles a user contributed to between two timestamps. API docs
- Pages with Property: Pages with one of page properties, such as disambiguation, displaytitle, defaultsort. API docs
- Namespaces: A scrolling list of namespaces. Ensure you check the relevant ones (e.g., '0' for Articles, '14' for Categories).
- Add to list: Fetches the pages and appends them to the processing list.
Rules (Find & Replace)

The core editing logic. wAwB allows you to define multiple Find and Replace rules. These are processed sequentially from top to bottom.
- Find: The text to search for.
- Replace: The text to insert.
- Regex toggle:
- Off (Default): Simple text replacement. Note: It replaces all occurrences, not just the first one.
- On: Uses JavaScript regular expressions.
- Flags: When regex is on, a small box appears (default
gmu). You can change regex flags here (e.g., removegto replace only the first match, addifor case-insensitivity). - {} JavaScript function: treat the input as a JavaScript function body, with access to a set of relevant variables.
Rule controls: Each rule box includes specific controls to manage your workflow:
Reorder: Use the Up and Down arrows on the left side of a rule to change its execution order. This is useful when one rule relies on the output of a previous rule.
Toggle active: Use the button to enable or disable a rule without deleting it.
- Blue: The rule is Active and will be applied.
- Grey: The rule is Inactive and will be ignored.
Delete: Permanently removes the rule.
External rules
wAwB supports loading external lists of find-and-replace rules, useful for applying common typo fixes or shared maintenance tasks. These rules are treated as regular expressions.
Do note that AutoWikiBrowser uses .NET regex engine, which behaves differently from the JavaScript regex engine used in web browsers. For example, in JavaScript characters like š, č, ü are seen as "non-word" characters (\W), so they will not be matched by the shortcut \w. The word boundary \b is always ASCII-only, even if Unicode-aware regex features are enabled using the u flag. Unicode lookarounds (?<!\p{L}) (not preceded by a letter) and (?!\p{L}) (not followed by a letter) should be used instead of the word boundary \b, with the u flag set.
- Project typos: Toggle "Project:AutoWikiBrowser/Typos" to fetch and apply rules defined on that wiki page. The script parses the page for valid XML tags. For additional details, see Project:AutoWikiBrowser/Typos on this or your local wiki.
- Local rules: Use the "Load file" button to upload a local text file containing your own rules. These rules are active for the current session only and are not saved within the wAwB project .json file.
Rule format
Both the wiki page and local files must use the following XML format. Rules with the `disabled` attribute will be ignored.
<Typo word="Description of the fix" find="\bteh\b" replace="the" />
<Typo word="Fixing header" find="==\s*External links\s*==" replace="== External links ==" />
<Typo word="Broken rule" find="..." replace="..." disabled />
Processing (The control center)
When you click Start, the tool enters "processing mode".
- Editing locked: The main editor and configuration inputs become Read-Only to prevent accidental changes during execution.
- Inspect mode: Unlike previous versions, the configuration panels (Source, Rules, Scripts) remain accessible. You can expand them to verify your regex or settings while the bot is running, though you cannot modify them until you click Stop.
- Summary: Enter your edit summary here. You can use variables (like
$xA) here to create dynamic summaries for every edit. - Buttons:
Start/Stop Toggles the processing session. "Start" locks the list and loads the first page. "Stop" unlocks the interface.
Diff Re-runs the diff calculation (useful if you manually edited the text area).
Skip Ignores the current page and loads the next one without saving.
Preview Renders, in the top right panel, a visual preview of the page in the user's current skin. All links in the preview will open in a new tab/window to prevent losing your work. The preview is generated on Wikimedia servers and is not instantaneous; use sparingly.
Save: Commits the edit to the wiki.
- List box: The text area at the bottom shows the queue of pages. You can manually edit this list.
- Toolbar:
- Sort (A-Z or Z-A): Sorts the list alphabetically.
- Dedup (Funnel): Removes duplicate page titles.
- Clear (Trash): Wipes the list.
Bot mode
Visible only if the user account belongs to the `bot` user group and is listed in the `enabledbots` configuration.
- Bot mode switch: If enabled, the script will automatically click "Save" after processing the rules.
- Delay (s): The wait time in seconds between edits.
- The tool automatically adds the `bot=1` flag to all API edit requests to avoid flooding Recent changes.
- The "Auto-Save" delay defaults to 10 seconds every time Bot mode is toggled on.
Skip (Filtering)
Define conditions under which a page should be automatically skipped.
- Redirects:
- Edit (Default): Edits the redirect page itself (e.g., fixing a typo in a redirect category).
- Follow: Resolves the redirect and edits the target page instead.
- Skip: Ignores redirects entirely.
- Skip logic:
- Skip if no changes: Crucial for maintenance runs. If your rules don't match anything, the page is skipped.
- Skip if missing: Prevents creating new pages by accident.
- Skip if exists: Useful if you are mass-creating pages and don't want to overwrite existing ones.
- Content filters: Skip the page if the text contains (or does not contain) a specific string or regex match.
- Category filters: Skip the page if it is (or is not) in any of the categories given as a list of category names (without the namespace prefix) separated by vertical bars, as in
First category|Second category|Third category.
Any JavaScript user function within wAwB can emit a skip command for even more powerful control of skipping.
Protection
Use this panel to "shield" parts of the text from your Rules. Protected text is temporarily hidden from the Find/Replace engine (using a uniques sequence of special characters)[note 2] and restored afterwards. As a second options, the same isolated parts of the text can be the only target of your replacement rules.
The shielding may not always be perfect, due to the complexities of wikitext, and should be used with great care. Some of the following protections may overlap—enable those that suit your needs best.
- Nowiki: Protects everything within
<nowiki>...</nowiki>, including the tags. - Comments: Protects HTML comments
<!-- ... -->. - Headers: Protects section headings, i. e. lines starting and ending with
==. - Templates: Protects content inside
{{...}}. By default, it protects all top-level templates (templates that are not nested inside other templates). However, which templates should be protected (or targeted) can be filtered by a regular expression. - Tables: Protects content inside
{|...|}, when the two delimiters start a new line. - Images: Protects content inside
[[Image:...|...|...]]. All local namespace aliases are supported:File:orImage:orSlika:orСлика:etc. - Refs: Protects citations inside
<ref>...</ref>. - Blocks: Protects code blocks such as
<math>,<pre>,<source>,<syntaxhighlight>,<code>,<gallery>. - Categories: Protects category links
[[Category:...|...]]. All local namespace aliases are supported. - File names: Protects the target filename in file links
[[File:...|and galleries where the File: prefix is provided. Local namespace aliases are supported - Targets: Protects targets of all wikilink-type wikitext, which includes the Files and Categories syntax.
- Example: In
[[Target|Label]], "Target" is protected, but "Label" can be modified by rules. - Example: In
[[Image:Some name.jpeg|thumb|Caption]], "Image:Some name.jpeg" is protected, the rest can be modified by rules.
- Example: In
- External links: Protects evertyhing inside of
[… …]. - URLs: Protects raw URLs starting with
http://orhttps://.
Page actions & maintenance
Watchlist control
Located at the top-right of the header, the
Watch/Unwatch button is available to all users.
- Empty star: The page is not on your watchlist. Click to watch.
- Filled star: The page is currently watched. Click to unwatch.
Administrator mode

For users with sufficient rights (administrators), wAwB includes a specialized toolkit for page maintenance. Administrators will see an additional accordion tab labeled Admin actions. To use these tools, you must first toggle the Enable admin actions switch.
Safe mode enforcement: When Admin mode is enabled, the tool enters a strict "Maintenance only" state:
- The editor becomes Read-Only (text cannot be modified manually).
- All find&replace rules and custom scripts are disabled to ensure you are seeing the exact, raw wikitext of the current revision.
- Standard "Save", "Preview", and "Diff" buttons are disabled.
Admin toolbar
When Admin mode is active and a valid page is loaded, three new buttons appear in the header:
Move: Moves the current page to the target title specified in the $xA list variable.
- Requirement: You must provide a target title in the list (e.g.,
OldPage|NewPage). If$xAis missing, this button remains disabled. - Options: Configure redirect suppression, talk page moving, and subpage moving in the Admin actions panel.
Delete: Deletes the current page immediately.
- Options: You can choose to automatically delete the associated Talk page in the settings.
Protect: Applies protection levels (Edit/Move protection with expiry) as defined in the Admin actions panel.
Advanced usage
1. Template filter
Instead of protecting or targeting all top-level templates on the page, a selection can be made using a regular expression. If the regular expression starts with a ^, the top-level templates will be chosen that match that regular expression. If it does not start with a ^, the whole top-level template will be protected if it contains the matched template anywhere within.
Example wikitext:
1. {{Top template|...|...{{other template|..}}...}}
2. {{Other template|..}}
If the template filter regex is other template, whatever is within {{Top template|...}} on line 1 gets protected, and everything that is within {{Other template|...}} on line 2 gets protected. If, however, the regex is ^other template, only the top-level {{Other template|...}} gets protection.[note 3]
The regular expression can contain alternations, such as infobox rail line|infobox railway|railway or ^(infobox heritage|intangible heritage).
2. Pre-parse mode
The pre-parse feature allows you to filter a large list of pages in the background, keeping only those that actually require changes based on your current configuration. This is useful for filtering out thousands of pages that don't match your regex rules without having to load them one by one in the editor.
Click the
Pre-parse button located directly below the page list.
The script first deduplicates the current list of titles, then fetches page content in batches (50 at a time) to minimize API calls. It applies your current regex rules, JavaScript, and Skip logic (including "Skip if text contains") to each page in memory. If a page matches a Skip rule or, optionally, results in no changes, it is removed from the list. The page that was kept is moved to the bottom of the list, below a ####STOP marker. The batch processing repeats until it reaches the ####STOP line. Click the button again (labeled "Stop pre-parse") to pause the process. When finished, your list will contain only the pages that require edits. You can then click "Start" to review and save them.
Note: Pre-parsing does not save edits to Wikipedia. It only filters your local list. Use the button sparingly, as the page is downloaded each time you start the process.
You can use special syntax in the page list to control the workflow:
- Comments
- Any line starting with
####is treated as a comment.
- The stop marker
- The specific line
####STOPacts as a hard barrier.- In manual mode: If the script encounters this line while clicking "Next" or "Save", it will automatically stop the process (equivalent to clicking the "Stop" button).
- In pre-parse mode: The script uses this marker to separate "Pending" pages (top) from "Processed/Kept" pages (bottom).
3. List variables
You can pass custom data for each page using pipe-separated values in the list box. This is useful for dynamic replacements based on per-page data.
- Syntax:
PageTitle|Value1|Value2|…
Each pipe-separated value in your page list generates variables $xA through $xZ directly in the Find and Replace fields of your rules. The variable $xx will hold the page title itself.
- Variables:
$xA= First value (Value1)$xB= Second value (Value2)- ... up to
$xZ $xx= Page title from the page list.
- Where to use:
- Replace rules: Use
$xAin the "Replace" or "Find" fields to insert the variable. - Edit summary: Use
$xAin the summary box for dynamic summaries (e.g., "Fixing link to $xA"). - Scripts: Accessed via the
varsobject (e.g.,vars.$xA).
- Replace rules: Use
The script injects the content of the variable into your search string before the search is performed. The behavior depends on whether you are using Regex mode or Normal mode.
Normal mode (regex off)
In this mode, the variable content is treated as literal text.
- Example list:
PageTitle|Apple - Variable:
$xA=Apple - Find:
I like $xA - Effect: The script searches for the literal string
"I like Apple".
Regex mode (regex on)
In this mode, the variable content is injected as raw regular expression code. This allows you to use variables as "regex macros" or to insert dynamic patterns. Warning: Because the injection is raw, special regex characters (like ., *, ?, ()) inside your variable will be interpreted as regex commands.
Scenarios |
|---|
|
Scenario A: dynamic pattern
Scenario B: Finding exact text (the "escaping" trap) If you want to match the exact text inside a variable while in Regex mode, you must ensure the variable content is escaped if it contains special characters.
|
Use cases |
|---|
|
4. Replace functions
For scenarios where simple regex replacement isn't enough (e.g., math calculations, conditional logic, or reformatting dates), wAwB supports JavaScript function replacement.
To use this feature:
- Enable Regex for the rule.
- Click the {} (Code) icon next to the regex toggle.
- The "Replace" field will change its placeholder to indicate code mode.
In this mode, the "Replace" field accepts the body of a JavaScript function. This function is executed for every match found by your regex.
Available variables
Your function has access to the following variables:
match: The full string matched by your regex (equivalent to$&).groups: An array of capturing groups (e.g.,groups[0]is$1,groups[1]is$2).vars: The global variables object containing your list parameters (e.g.,vars.$xx,vars.$xA).shared: An object, initially empty, shared between all scripts for the current page.
Return value
- You must
returna string to replace the matched text. - If you return
undefined(or nothing), the original text is preserved (no change). - If your code throws an error, the original text is preserved.
Examples |
|---|
var km = parseInt(groups[0]);
return (km * 1000) + " m";
var catName = groups[0];
// If category is "Stub", remove it (return empty string)
if (catName === "Stub") return "";
// Otherwise, keep it as is
return match;
// Inject the value of $xA from your page list
return "The value is " + vars.$xA;
|
5. Scripts
For complex logic that cannot be handled by simple Find/Replace you can write JavaScript functions that accept three arguments: text (the page content), vars (the variables from the titles list), and shared (an initially empty object shared among all the functions, for the current page)
Using input boxes
There are two boxes to enter the bodies of JavaScript functions acting on the text before and after it has been processed by the set of Rules. The bodies of these functions can contain other functions, and should return the transformed article text. For example, the following function body will result in a template being added on top, and the article text being lowercased.
return "{{Unreferenced}}\n" + text.toLowerCase();
External libraries
An external library of user-defined functions for use in the pre- and post-process scripts or the replacement rules with JavaScript enabled can be loaded and saved with the project via a simple interface on top of the Scripts section. While the name of the library file is preserved for future reference, the external file is not linked with the project in any way, so any changes to it will only take effect once it is loaded and saved with the project.
The library can be further edited in wAwB. Two functions, namely wAwB_Pre = function(text, vars, shared) and wAwB_Post = function(text, vars, shared) can be defined, whose bodies will serve as the bodies of the two pre- and post-processing functions described above, if the respective input boxes are found to be empty (and if the respective eponymous global functions from the following section have not been defined).
Using global hooks
Instead of typing code into the small boxes every time, you can define global functions window.wAwB_Pre = function(text, vars, shared) and window.wAwB_Post = function(text, vars, shared) in your common.js file or browser console. The tool will automatically use them if the script boxes are empty.
Examples |
|---|
|
Pre-Processing (before Rules): window.wAwB_Pre = function(text, vars, shared) {
// Example: Use a variable from the list
if (vars.$xA) {
return text + "\nSee also: [[" + vars.$xA + "]]";
}
return text;
};
Post-Processing (after Rules): window.wAwB_Post = function(text, vars, shared) {
// Example: specific logic to clean up artifacts
function doTrim(t) {
return t.trim();
};
return doTrim(text);
};
|
The code inside these functions should be self-contained. If calling other user-defined functions is needed, they should be defined within window.wAwB_Pre and window.wAwB_Post, as shown in the second example. No other code is sent to the worker, and the worker has no access to window or document.
6. Advanced scripting
wAwB includes advanced scripting capabilities that allow you to pass data between different processing stages and conditionally skip pages based on complex logic.
The shared object
The shared object persists across the entire processing chain for a single page. You can write to it in the Pre-Process script, read/modify it in your individual regex rules scripts, and use it again in the Post-Process script.
- Usage:
sharedis available as a variable in Pre/Post scripts and as the 4th argument in the individual rules functions. - Scope: It is unique to the page currently being processed and is reset for the next page.
Examples |
|---|
|
Flagging an issue in Pre-process and acting on it in Post-process Pre-process script: // Detect if the page started with a specific template
shared.hadMaintenanceTag = text.includes("{{Under construction");
return text;
Post-process script: // If we removed the tag, add a custom summary note
if (shared.hadMaintenanceTag && !text.includes("{{Under construction")) {
console.log("Warning: Maintenance tag removed");
}
return text;
|
Conditional skipping
You can instruct wAwB to skip a page entirely from within your JavaScript logic. This is useful for complex criteria that cannot be handled by simple "Contains/Not nontains" filters.
Instead of returning the text string, your function should return an object with skip: true.
Syntax:
return { skip: true, reason: "Your reason here" };
Examples |
|---|
|
Example: Skip short pages Pre-process script: if (text.length < 500) {
return { skip: true, reason: "Page too short (<500 chars)" };
}
return text;
Example: Skip if a specific rule fired
You can combine this with the
if (shared.foundBadThing) {
return { skip: true, reason: "Skipped to avoid editing bad pattern manually" };
}
return text;
|
Fetching parsed content from the server
The pre- and post-processing scripts can interact with the server (via API:Parse) and fetch the parsed version of the content sent to them. This may include the protected wikitext, a specific targeted part of the original wikitext, or even multiple targeted parts (fetched consecutively, which may risk a worker timeout!). This can be useful, for example, to check whether the parsed output adds any categories.
Example |
|---|
Target a template, then send its code to the server to check whether the parsed version would add the page to Category:My unwanted category. If it would, skip the page.
async function wAwB_Post(text, vars, shared) {
try {
// Note: Use the absolute URL because workers have blob:// origins
const apiUrl = self.location.origin + '/w/api.php';
// mediawiki.org/wiki/API:Parse
const params = new URLSearchParams({
action: 'parse',
format: 'json',
text: text,
prop: 'categories',
contentmodel: 'wikitext',
origin: '*'
});
const response = await fetch(apiUrl, {
method: 'POST',
body: params
});
const data = await response.json();
// Logic...
if (data.parse && data.parse.categories) {
var categories = data.parse.categories;
// Extract just the category names
var categoryNames = categories.map(function(cat) {
return cat['*'];
});
console.log(categoryNames);
if (categoryNames.contains("My unwanted category")) {
return {
skip: true,
reason: "Skipped because..."
};
}
}
return text;
} catch (e) {
console.log(e.message);
return {
skip: true,
reason: "Fetch error: " + e.message
};
}
}
|
Notes
- wrong A? write B. / where A, write B / wish A were B / word A → word B / webAWB / wAwB
- If these special non-printable Unicode characters (uE000 [uE010–uE019]+ uE001) show up in your edits, make sure your replacement rules do not touch them, breaking the shielding mechanism.
- Internally, the top-level template is selected based on whether anything captured inside the balanced
{{and}}pairs matches^{{regex, if the raw regex starts with ^, or{{regexotherwise.