//<pre><nowiki>
/* segregate-refs.js: A user script to simplify editing of articles
using inline ref tags with the Cite.php extension to MediaWiki.
Copyright (c) 2010, PleaseStand
This software is licensed under these licenses:
1. Creative Commons Attribution-Share Alike 3.0 Unported License
(see <http://creativecommons.org/licenses/by-sa/3.0/> for the text)
2. GNU Free Documentation License, any published version.
(see <http://www.gnu.org/copyleft/fdl.html> for the text)
3. Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
You may select the license(s) of your choice if you wish to copy, modify, or
distribute this software. If you modify the software and do not wish to
license your changes under one or more of the licenses, please remove
the license(s) from the list above.
*/
/*global window, addOnloadHook, SegregateRefsJsL10n, SegregateRefsJsAllowConversion,
wikEdUseWikEd, WikEdUpdateTextarea, WikEdUpdateFrame*/
SegregateRefsJsEmptyRefsWarningGiven, SegregateRefsJsAllowConversion,
SegregateRefsJsCompleteSearch, wikEdUseWikEd, WikEdUpdateTextarea,
// <nowiki>
WikEdUpdateFrame*/
// Translate the right-hand side of these if necessary.
// var SegregateRefsJsL10n = {
var SegregateRefsJsMsgs = {
version: 1.11,
buttonText: "Segregate refs for editing",
buttonStyle: "background: #dfd;",
buttonConvertText: "Migrate article to LDR",
buttonConvertStyle: "background: #fdd;",
autoWord: "Auto",
convertRefsWarning: "WARNING: You need consensus to migrate an article to list-defined references format (LDR) BEFORE you do so.\n\nClick Cancel now if consensus has not been established in favor of this migration. If there is consensus to make the conversion, click OK to do so.",
emptyRefsWarning: "IMPORTANT: This page includes one or more named " +
groupPrompt: "Please enter the name of a group (as it appears in the wikitext, including any quotes). Leave this blank if unsure.",
"footnotes of which the first occurrence(s) have no contents, which is " +
refsHeader: "Inline footnotes",
"not best practice. This script does not harm such footnotes, however " +
convertHeader: "Generated refs list",
"you should be aware that this script ONLY CHECKS THE FIRST REF TAG " +
refsCommentComplete: "<!-- Converted to LDR format\n using [[User:PleaseStand/References segregator]] -->\n\n",
"it finds for the actual citation or note text, and you must work within " +
convertSummary: "Converted footnotes to LDR format (using [[User:PleaseStand/References segregator|segregate-refs]])",
"this limitation. Any change to the empty ref tag will replace the " +
convertFurther: "This script has done most of the work. However, you still need to do the following:\n\n* Insert the refs list in the new textbox into the proper place in the wikitext.\n* If converting a special group, optionally remove the group attributes.\n* Replace all autogenerated names with human-generated names.\n\nYou can do the above with the Find/Replace command in many text editors. (Always use the quoted form of the attributes.) Then, paste the text back into the edit form and save the page.",
"footnote entirely and leave the old note text hidden.\n\n" +
integrateWarning: "The refs listed below are missing from the text. If you continue, they will be permanently deleted. Are you sure?\n\nUnused refs: "
"BEFORE concluding from the footnotes list that a ref is in fact empty, " +
"please manually check all identically-named ref tags for the contents. " +
"\n\nDo you acknowledge this limitation of the script? DO NOT CLICK OK " +
"UNTIL YOU HAVE READ THE ABOVE INFORMATION.",
convertRefsWarning: "WARNING: You need consensus to migrate an article " +
"to list-defined references format (LDR) BEFORE you do so.\n\nClick " +
"Cancel now if consensus has not been established in favor of this " +
"migration. If there is consensus to make the conversion, click OK to " +
"do so.",
groupPrompt: "Please enter the name of a group (as it appears in the " +
"wikitext, including any quotes). Leave this blank if unsure.",
refsHeader: "Inline footnotes",
convertHeader: "Generated refs list",
refsCommentIncomplete: "<!-- This list of footnotes may be incomplete. " +
"Do not use for conversion purposes. -->\n\n",
refsCommentComplete: "<!-- Converted to LDR format\n" +
" using [[User:PleaseStand/References segregator]] -->\n\n",
convertSummary: "Converted footnotes to LDR format (using " +
"[[User:PleaseStand/References segregator|segregate-refs]])",
convertFurther: "This script has done most of the work. However, you still " +
"need to do the following:\n\n* Insert the refs list in the new textbox " +
"into the proper place in the wikitext.\n* If converting a special " +
"group, optionally remove the group attributes.\n* Replace all " +
"autogenerated names with human-generated names.\n\nYou can do the above " +
"with the Find/Replace command in many text editors. (Always use the " +
"quoted form of the attributes.) Then, paste the text back into the edit " +
"form and save the page.",
integrateWarning: "The refs listed below are missing from the text. If you " +
"continue, they will be permanently deleted. Are you sure?\n\nUnused refs: "
};
( function ( $ ) {
// Begin encapsulation (prevent interference with other scripts)
function SegregateRefsJs(){
var editForm, refsDiv, refsH2, mainTextbox, refsTextbox, randPrefix, messages,
// Semi-global variables (private to this script)
refsButton, convertButton, unloadHandlerRegistered = false;
var editForm; var refsDiv; var refsH2; var mainTextbox; var refsTextbox;
var randPrefix; var messages; var refsButton; var convertButton; var complete;
/**
// Extend the string object with new methods
* Unquote a wikitext tag attribute.
// Begin with the prefix "Ps" to avoid name clashes
*
* @param string quotedValue
* @return string
*/
function htmlUnquote( quotedValue ) {
var d = document.createElement( 'div' );
d.innerHTML = '<input value=' + quotedValue + '></input>';
return d.firstChild.value;
}
/**
// Add support for setting a slice of a string.
* Quote a wikitext tag attribute, choosing single quotes versus
// (Only works with positive indices.)
* double quotes depending on which is shorter.
String.prototype.PsSetSlice = function(replacement, indexFrom, indexTo) {
*
if(typeof indexTo == "undefined") {
* @param string value
return this.slice(0, indexFrom) + replacement;
* @return string
}
*/
return this.slice(0, indexFrom) + replacement + this.slice(indexTo);
function htmlQuote( value ) {
};
var sQ, dQ;
value = value.replace( /\&/g, '&' );
// Add support for unquoting from HTML-quoted form.
sQ = "'" + value.replace( /'/g, ''' ) + "'",
String.prototype.PsHTMLUnquote = function() {
dQ = '"' + value.replace( /"/g, '"' ) + '"';
// Let's use the browser's functionality for the hard work,
// since MediaWiki/PHP supports many different HTML entities.
// (Note: innerHTML is not W3C-standard)
var d = window.document.createElement("div");
d.innerHTML = "<input value=" + this + "></input>";
return d.firstChild.value;
};
return sQ.length < dQ.length ? sQ : dQ;
// Add support for quoting using HTML quotes. Chooses single quotes versus
}
// double quotes depending on which is shorter.
String.prototype.PsHTMLQuote = function() {
// Escape ampersands
var s = this.replace(/\&/g, "&");
// Try both kinds of quotes
var sQ = "'" + s.replace(/'/g, "'") + "'";
var dQ = '"' + s.replace(/"/g, """) + '"';
// Choose the shorter, preferring double quotes if equal in length
return (sQ.length < dQ.length ? sQ : dQ);
};
// OBJECTS
// RefScanner: UseLooks for identifying ref tags in the text., (Noskipping nestedproblematic refsextension please)tags.
// For example, "references" may contain out-of-line refs, which should be skipped.
function RefScanner(argWikiText) {
function RefScanner( argWikiText ) {
this.wikiText = argWikiText;
this.wikiText = argWikiText;
// The tags listed below other than "ref" are there for an obvious reason.
this.refScanRegex = /(?:<!--[\s\S]*?-->|<(nowiki|source|references|ref)(?:|\s(?:[^"']|"[^"]*"|'[^']*')*?)(?:\/>|(?:>[\s\S]*?<\/\1(?:|\s[^>]*)>)))/gi;
// NB: "references" is here to prevent out-of-line refs from being returned.
this.refScanRegex = /(?:<!--[\s\S]*?-->|<(nowiki|source|references|ref)(?:\s|(?:[^"']|"[^"]*"|'[^']*')*?)(?:\/>|(?:>[\s\S]*?<\/\1(?:|\s[^>]*)>)))/gi;
}
RefScanner.prototype = {
// ReturnsGet the next ref found infrom the text.
RefScanner.prototype.getRef getRef:= function getRef() {
var results = [0,0];
do {
while(results[1].toString().toLowerCase() != "ref") {
results = this.refScanRegex.exec( this.wikiText );
if ( if(!results ) {
return null;
}
}
if if(typeof results[1] === "undefined" ) {
results = [0, 0];
}
}
} while ( results[1].toString().toLowerCase() !== 'ref' );
}
return results[0];
}
};
// RefParser: Use for extractingExtracts attributes from ref tags.
function RefParser( argWikiText ) {
// This is mostly a copy of refScanRegex, except that the whole string must be a ref,
this.wikiText = argWikiText;
// and no more, and two parts are extracted: $1=attributes, $2=remaining portion of ref
// The below regex is mostly a copy of the refScanRegex above, except that
var refParseRegex = /^<ref(|\s(?:[^"']|"[^"]*"|'[^']*')*?)(\/>|(?:>[\s\S]*?<\/ref(?:|\s[^>]*)>))$/i;
// the whole string must be a ref, and no more, and two parts are extracted:
// $1=attributes, $2=remaining portion of ref
this.wikiText = argWikiText;
var refParseRegex = /^<ref(|\s(?:[^"']|"[^"]*"|'[^']*')*?)(\/>|(?:>[\s\S]*?<\/ref(?:|\s[^>]*)>))$/i;
this.parsedRef = refParseRegex.exec( this.wikiText );
if ( !this.parsedRef ) {
throw new Error(" 'invalid ref"' );
}
}
RefParser.prototype = {
// Get all attributes of the tag.
getAttributes: function getAttributes() {
RefParser.prototype.getAttributes = function () {
// In this regex, we need to extract a single name-value pair at a time.
// In this regex, we need to extract a single name-value pair at a time.
var attParseRegex = /\s([^\s=>]+)\s*=\s*("[^"]*"|'[^']*'|[^\s"']*)/g;
var attParseRegex = /\s([^\s=>]+)\s*=\s*("[^"]*"|'[^']*'|[^\s"']*)/g;
if(!this.parsedRef) {
if ( !this.parsedRef ) {
return null;
return null;
}
}
var attributes = {};
var attributes = Object.create( null ), results;
while(true) {
while ( var( results = attParseRegex.exec( this.parsedRef[1] ); ) ) {
attributes[results[1].toLowerCase()] = htmlUnquote( results[2] );
if(!results) {
}
break;
return attributes;
}
attributes[results[1].toLowerCase()] = results[2].PsHTMLUnquote();
}
return attributes;
}
};
/**
// FUNCTIONS
* Segregate refs from content.
*
* @param string argWikiText The original wikitext
* @param string group The name of the ref group to process (default group is '')
* @param bool caseCues Mark the original ref code locations using capitalization?
* @return Object
*/
function segregateRefs( argWikiText, group, caseCues ) {
var prefixChars, randNo, randPrefix, refPreferred, scanner, ref, parser, attributes,
refGroup, refName, refStored, refEmpty, refLong, unnamedRefs = 0,
refNames = Object.create( null ), refCodes = [], refShort, outWikiText = '', offset = 0;
// Create a random prefix for autogenerated ref names
// segregateRefs: Use for segregating refs from content.
prefixChars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
// If completeSearch == true, the function looks in all occurrences for ref
randNo = Math.floor( Math.random() * ( prefixChars.length * prefixChars.length ) );
// contents. If completeSearch == false, the function only checks the first.
randPrefix = messages.autoWord
// group is the reference group to limit the operation to. The empty string
+ prefixChars.charAt( Math.floor( randNo / prefixChars.length ) )
// refers to all ungrouped refs. caseCues is whether or not to use
+ prefixChars.charAt(randNo % prefixChars.length) +
// capitalization to designate a preferred ref code ___location.
'-';
function segregateRefs(argWikiText, completeSearch, group, caseCues) {
// Create athe randombeginning prefixof the code for autogenerateda preferred ref names.___location
refPreferred = caseCues ? '<REF ' : '<ref ';
// in theory this has a 1/1296 probability of collision - extremely low
var prefixChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
scanner = new RefScanner( argWikiText );
var randNo = Math.floor(Math.random() *
(prefixChars.length * prefixChars.length));
while ( ( ref = scanner.getRef() ) ) {
randPrefix = messages.autoWord + prefixChars.charAt(Math.floor(randNo /
parser = new RefParser( ref );
prefixChars.length)) + prefixChars.charAt(randNo % prefixChars.length) +
attributes = parser.getAttributes();
"-";
refGroup = attributes.group || '';
// Create the beginning of the code for a preferred ref ___location
if ( group != refGroup ) {
var refPreferred = caseCues ? "<REF " : "<ref ";
// The ref is in a different group
continue;
// Variables for the main code
}
var scanner = new RefScanner(argWikiText);
var unnamedRefs = 0; var refNames = {}; var ref; var refStored;
if var parser; var( attributes; var refName;.name var!== refLong;undefined var) refShort;{
// The ref already has a name (possibly the empty string)
var refCodes = []; var refEmpty; var emptyRefsWarningGiven = false;
refName = attributes.name;
var refGroup;
refStored = refName in refNames;
refEmpty = parser.parsedRef[2].slice( -2 ) == '/>' ||
// Disable the empty refs warning (see below) if the user has disabled it
parser.parsedRef[2].slice( 0, 3 ) == '></';
if(typeof SegregateRefsJsEmptyRefsWarningGiven != "undefined" &&
refLong = ref;
SegregateRefsJsEmptyRefsWarningGiven) {
emptyRefsWarningGiven = true;
} else {
}
// We have to autogenerate one
refName = randPrefix + ( ++unnamedRefs ).toString(10);
while((ref = scanner.getRef())) {
refStored = false;
parser = new RefParser(ref);
refEmpty = false;
attributes = parser.getAttributes();
refLong = '<ref name=' + htmlQuote( refName ) +
parser.parsedRef[1] + parser.parsedRef[2];
// First make sure that the ref is in the right group.
}
refGroup = attributes.hasOwnProperty("group") ? attributes.group : "";
if(group != refGroup) {
if ( !refStored ) {
continue;
// Found the first ref of this name
}
refNames[refName] = {
code: refCodes.length,
// Does the ref have a name?
empty: refEmpty
// (Note: No matter how incorrect it seems, the empty string is
};
// an acceptable ref name to the MediaWiki parser, as verified by
refCodes[refNames[refName].code] = refLong;
// informal testing.)
if(!attributes.hasOwnProperty("name")) {
// Make a short code for the ref
// Bad: it doesn't have one - create a name for it
if ( refEmpty ) {
refStored = false;
refShort = refLong;
refEmpty = false;
} else if ( refGroup === '' ) {
refName = randPrefix + (++unnamedRefs).toString(10);
refShort = refPreferred + 'name=' + htmlQuote( refName ) + '/>';
// Change the corresponding ref code
} else {
refLong = "<ref name=" + refName.PsHTMLQuote() +
refShort = refPreferred + 'name=' + htmlQuote( refName ) +
parser.parsedRef[1] + parser.parsedRef[2];
' group=' + htmlQuote( refGroup ) + '/>';
} else {
}
// Good: it has a name.
refName = attributes.name;
} else if ( !refEmpty && refNames[refName].empty ) {
refLong = ref;
// Already found an empty ref under this name, yet this one is non-empty
// Check if the ref name has already been seen.
// Fill in the long code for the existing entry
refStored = refNames.hasOwnProperty(refName);
refCodes[refNames[refName].code] = refLong;
// Check if the ref has no contents.
refNames[refName].empty = false;
refEmpty = (parser.parsedRef[2].slice(-2) == "/>") ||
(parser.parsedRef[2].slice(0, 3) == "></");
// Make a short code for the ref
// Since this script, when not set in complete search mode, checks
refShort = refPreferred + 'name=' + htmlQuote( refName );
// only the first occurrence of a ref for contents, inform the user
if ( refGroup !== '' ) {
// of this limitation if it may pose a problem.
refShort += ' group=' + htmlQuote( refGroup ) + '/>';
if(!completeSearch && !emptyRefsWarningGiven && !refStored) {
}
if(refEmpty) {
refShort += '/>';
if(!window.confirm(messages.emptyRefsWarning)) {
return false;
} else {
}
// Leave the ref as-is
emptyRefsWarningGiven = true;
refShort = caseCues ? refLong.replace( /^<REF/, "<ref" ) : refLong;
}
}
}
}
// Replace the long code with the short code
outWikiText += argWikiText.slice( offset, scanner.refScanRegex.lastIndex - ref.length );
// Is the ref's name unique?
outWikiText += refShort;
if(!refStored) {
offset = scanner.refScanRegex.lastIndex;
// Unique: add it to the list of refs
}
refNames[refName] = {
code: refCodes.length,
outWikiText += argWikiText.slice( offset );
empty: refEmpty
};
return {
refCodes[refNames[refName].code] = refLong;
wikiText: outWikiText,
// Make a short code for the ref
refCodes: refCodes,
if(!refGroup.length) {
randPrefix: randPrefix
refShort = refPreferred + "name=" +
};
refName.PsHTMLQuote() + "/>";
} else {
refShort = refPreferred + "name=" + refName.PsHTMLQuote() +
" " + "group=" + refGroup.PsHTMLQuote() + "/>";
}
// Otherwise, is the current longcode not empty?
// (only when in complete search mode, and when another non-empty,
// same-named ref has not been encountered)
} else if (completeSearch && !refEmpty && refNames[refName].empty) {
// Not empty: fill in the long code and make a short code
refCodes[refNames[refName].code] = refLong;
refNames[refName].empty = false;
if(!refGroup.length) {
refShort = refPreferred + "name=" +
refName.PsHTMLQuote() + "/>";
} else {
refShort = refPreferred + "name=" + refName.PsHTMLQuote() +
" " + "group=" + refGroup.PsHTMLQuote() + "/>";
}
} else {
// Leave the ref as-is in the original wikitext
// (except if caseCues apply)
if(caseCues) {
refShort = refLong.replace(/^<REF/, "<ref");
} else {
refShort = refLong;
}
}
// Replace the long code with the short code
scanner.wikiText = scanner.wikiText.PsSetSlice(refShort,
scanner.refScanRegex.lastIndex - ref.length,
scanner.refScanRegex.lastIndex);
// Update lastIndex accordingly
scanner.refScanRegex.lastIndex += refShort.length - ref.length;
}
return {
wikiText: scanner.wikiText,
refCodes: refCodes,
randPrefix: randPrefix
};
}
/**
// integrateRefs: Use for inserting ref contents back into text
* Insert ref contents back into the text.
*
* @param string argWikiText The wikitext without ref contents
* @param string argRefText The ref contents
* @param string randPrefix The randPrefix value returned by segregateRefs()
* @param string caseCues The caseCues argument passed to segregateRefs()
*/
function integrateRefs(argWikiText, argRefText, randPrefix, caseCues) {
// A function to removeRemove an autogenerated ref name (if possible).
function cleanRefLong(dirtyRef) {
var cleanRegex = /^<(ref) name=(?:"[^"]*"|'[^']*'|[^\s"']*)/i;
return dirtyRef.replace(cleanRegex, "'<$1"');
}
}
var scanner, ref, parser, attributes, refCodes = Object.create( null ), usageFreq = Object.create( null ),
// Variables for the main code
preferredRef = Object.create( null ), refLong, outWikiText = '', offset = 0;
var scanner; var ref; var parser; var attributes; var refCodes = {};
var usageFreq = {}; var preferredRef = {}; var refLong;
// First, we build an associative array of all the ref codes
// First,that we buildmight anneed associativeto arrayput ofback allinto the ref codestext.
scanner = new RefScanner( argRefText );
// that we might need to put back into the text.
while ( ( ref = scanner.getRef() ) ) {
scanner = new RefScanner(argRefText);
parser = new RefParser( ref );
while((ref = scanner.getRef())) {
attributes = parser = new RefParser.getAttributes(ref);
if ( attributes.name !== parser.getAttributes(undefined ); {
// Only use the first ref having each name
if(attributes.hasOwnProperty("name")) {
if ( !( attributes.name in refCodes ) ) {
// Only use the first ref with each name
refCodes[attributes.name] = ref;
if(!refCodes.hasOwnProperty(attributes.name)) {
}
refCodes[attributes.name] = ref;
}
}
}
}
}
// Next, we build an associative array that holds the usage frequency
// of every ref name used in text, and whether there is a preferred ref,
// Next, we build an associative array that holds the usage frequency
// if caseCues are enabled.
// of every ref name used in text, and whether there is a preferred ref,
scanner = new RefScanner( argWikiText );
// if caseCues are selected.
while ( ( ref = scanner.getRef() ) ) {
scanner = new RefScanner(argWikiText);
parser = new RefParser( ref );
while((ref = scanner.getRef())) {
attributes = parser = new RefParser.getAttributes(ref);
if ( attributes.name !== parser.getAttributes(undefined ); {
if ( !( attributes.name in usageFreq ) ) {
if(attributes.hasOwnProperty("name")) {
if(! usageFreq.hasOwnProperty([attributes.name))] = {1;
} else {
// We found a new name
usageFreq[attributes.name] = 1++;
}
} else {
if ( caseCues && ref.slice( 0, 4 ) == '<REF' ) {
// We already found this name
usageFreq preferredRef[attributes.name]++ = true;
}
}
}
if(caseCues) {
}
if(ref.slice(0, 4) == "<REF") {
preferredRef[attributes.name] = true;
// Finally, we go through the text again and this time we insert the
}
// ref codes where we need to, but only in the first }place
// a ref name appears (or the first preferred ___location).
}
scanner = new RefScanner( argWikiText );
}
while ( ( ref = scanner.getRef() ) ) {
window.alert(JSON.stringify(preferredRef));
parser = new RefParser( ref );
attributes = parser.getAttributes();
// Finally, we go through the text again and this time we insert the
if ( 'name' in attributes ) {
// ref codes where we need to, but only in the first place
// aIs refthis name appears (oron the first preferredreplacement ___location).list?
if ( attributes.name in refCodes ) {
scanner = new RefScanner(argWikiText);
while((ref = scanner.getRef())) {
// If we are using caseCues, and another ___location is
parser = new RefParser(ref);
// preferred, skip to the next ref.
attributes = parser.getAttributes();
if ( caseCues && if(attributes.hasOwnProperty("name")) {in preferredRef &&
ref.slice( 0, 4 ) != '<REF'
// Is this name on the replacement list?
) {
if(refCodes.hasOwnProperty(attributes.name)) {
continue;
}
// If we are using caseCues, and another ___location is
// preferred, skip to the next ref.
// Is this name an autogenerated name?
if(caseCues && preferredRef.hasOwnProperty(attributes.name) &&
if ( refattributes.name.slice( 0, 4randPrefix.length ) !== randPrefix "<REF") {
// Yes: is the name used multiple times?
continue;
if ( usageFreq[attributes.name] > 1 ) {
}
// Multiple: the replacement code should be the same
// as that stored in the ref textbox.
// Is this name an autogenerated name?
refLong = refCodes[attributes.name];
if(attributes.name.slice(0, randPrefix.length) == randPrefix) {
} else {
// Yes: is the name used multiple times?
// Single: replacement code must not include the name,
if(usageFreq[attributes.name] > 1) {
// at least not if the citation was untouched.
// Multiple: the replacement code should be the same
// (We don't want to add unnecessary autonames)
// as that stored in the ref textbox.
refLong = cleanRefLong( refCodes[attributes.name] );
}
} else {
} else {
// Single: replacement code must not include the name,
// No: the replacement code should be the same
// at least not if the citation was untouched.
// as that stored in the ref textbox.
// (We don't want to add unnecessary autonames)
// (We want to preserve all human-generated names)
refLong = cleanRefLong(refCodes[attributes.name]);
refLong = refCodes[attributes.name];
}
}
} else {
// No: the replacement code should be the same
// Replace the short code with the long code
// as that stored in the ref textbox.
outWikiText += argWikiText.slice( offset, scanner.refScanRegex.lastIndex - ref.length );
// (We want to preserve all human-generated names)
outWikiText += refLong;
refLong = refCodes[attributes.name];
offset = scanner.refScanRegex.lastIndex;
}
// ReplaceDelete the short codename withfrom the longreplacement codelist
delete refCodes[attributes.name];
scanner.wikiText = scanner.wikiText.PsSetSlice(refLong,
}
scanner.refScanRegex.lastIndex - ref.length,
}
scanner.refScanRegex.lastIndex);
}
// Update lastIndex accordingly
scanner.refScanRegex.lastIndex += refLong.length - ref.length;
outWikiText += argWikiText.slice( offset );
// Delete the name from the replacement list
return {
delete refCodes[attributes.name];
wikiText: outWikiText,
}
unusedRefs: refCodes
}
};
}
// Return both the combined output and the ref codes that were not used.
return {wikiText: scanner.wikiText, unusedRefs: refCodes};
}
/**
function submitHandler() {
* Clear the undo history of a textarea by removing it from the document
// Local variables
* and then inserting it again.
var result; var refName; var unusedRefNamesQuoted = [];
*
* @param HTMLTextareaElement ta The textarea element
// Do the actual integration work
*/
result = integrateRefs(mainTextbox.value, refsTextbox.value,
function clearUndoHistory(ta) {
randPrefix, complete);
var pn = ta.parentNode, ns = ta.nextSibling;
pn.insertBefore(pn.removeChild(ta), ns);
// Find all unused ref names
}
for(refName in result.unusedRefs) {
if(result.unusedRefs.hasOwnProperty(refName)) {
function unloadHandler(evt) {
unusedRefNamesQuoted.push(refName.PsHTMLQuote());
// Local variables
}
var result, refName, unusedRefNamesQuoted = [];
}
// If any refs are unused, warn and allow the user to cancel
// wikEd compatibility (frame -> textarea)
if(unusedRefNamesQuoted.length) {
if(typeof wikEdUseWikEd != "undefined" && wikEdUseWikEd) {
if(!window.confirm(messages.integrateWarning +
WikEdUpdateTextarea();
unusedRefNamesQuoted.join(", "))) {
}
// Don't submit form
return false;
// Do the actual integration work
}
result = integrateRefs(mainTextbox.value, refsTextbox.value, randPrefix, true);
}
// Find all unused ref names
// Otherwise, update the textbox.
for(refName in result.unusedRefs) {
mainTextbox.value = result.wikiText;
unusedRefNamesQuoted.push(htmlQuote(refName));
}
// We can delete the header and refs textbox now
// If any refs are unused, warn and allow the user to cancel;
refsDiv.removeChild(refsH2);
// we do not do this on unload because it is not really possible.
refsDiv.removeChild(refsTextbox);
if(evt.type == "submit" && unusedRefNamesQuoted.length) {
if(!window.confirm(messages.integrateWarning +
// Deactivate this submit handler and run any previously registered handler
unusedRefNamesQuoted.join(", "))) {
editForm.onsubmit = null;
// Don't submit form
if(typeof editForm.PsOnsubmit == "function") {
evt.preventDefault();
editForm.onsubmit = editForm.PsOnsubmit;
return false;
editForm.onsubmit.apply(this, arguments);
}
}
}
return true;
// Otherwise, update the textbox.
mainTextbox.value = result.wikiText;
// wikEd compatibility (textarea -> frame)
if(typeof wikEdUseWikEd != "undefined" && wikEdUseWikEd) {
WikEdUpdateFrame();
}
// Deactivate this event handler
window.removeEventListener("submit", unloadHandler, false);
window.removeEventListener("unload", unloadHandler, false);
unloadHandlerRegistered = false;
// We can delete the header and refs textbox now
refsDiv.removeChild(refsH2);
refsDiv.removeChild(refsTextbox);
return true;
}
function refsButtonHandler() { // Called when script activated by button click
// Both buttons should disappear
if(convertButton.parentNode){
convertButton.parentNode.removeChild(convertButton);
}
}
if(refsButton.parentNode) {
refsButton.parentNode.removeChild(refsButton);
}
}
// wikEd compatibility (frame -> textarea)
// Allow for the experimental ability to use the complete search mode
if(typeof wikEdUseWikEd != "undefined" && wikEdUseWikEd) {
// when segregating refs for editing.
WikEdUpdateTextarea();
if(typeof SegregateRefsJsCompleteSearch != "undefined" &&
}
SegregateRefsJsCompleteSearch) {
complete = true;
// Do the actual segregation work and save the random prefix
} else {
var segFormat = segregateRefs(mainTextbox.value, "", true);
complete = false;
if(!segFormat) {
}
return false;
}
// Do the actual segregation work and save the random prefix
randPrefix = segFormat.randPrefix;
var segFormat = segregateRefs(mainTextbox.value, complete, "", complete);
if(!segFormat) {
// Update the textbox
return false;
mainTextbox.value = segFormat.wikiText;
}
clearUndoHistory(mainTextbox);
randPrefix = segFormat.randPrefix;
// wikEd compatibility (frametextarea -> textareaframe)
if(typeof wikEdUseWikEd != "undefined" && wikEdUseWikEd) {
WikEdUpdateFrame();
WikEdUpdateTextarea();
}
}
// Inline refs header
// Update the textbox
refsH2 = document.createElement("h2");
mainTextbox.value = segFormat.wikiText;
refsH2.appendChild(document.createTextNode(messages.refsHeader));
// wikEd compatibility (textarea -> frame)
refsH2.style.borderColor = "silver";
if(typeof wikEdUseWikEd != "undefined" && wikEdUseWikEd) {
refsH2.style.borderStyle = "solid";
WikEdUpdateFrame();
refsH2.style.borderWidth = "1px 0";
}
refsH2.style.fontSize = "100%";
refsH2.style.fontWeight = "100%";
// Inline refs header
refsH2.style.lineHeight = "normal";
refsH2 = window.document.createElement("h2");
refsH2.style.margin = "0";
refsH2.appendChild(window.document.createTextNode(messages.refsHeader));
refsH2.style.padding = "0.5em 0 0";
refsH2.style.textAlign = "center";
// Inline refs textbox
refsTextbox = window.document.createElement("textarea");
// Inline refs textbox
refsTextbox.id = "PsRefsTextbox";
refsTextbox.value = messagesdocument.refsCommentIncomplete +createElement("textarea");
refsTextbox.id = "PsRefsTextbox";
segFormat.refCodes.join("\n\n");
refsTextbox.rowsvalue = MathsegFormat.floorrefCodes.join(mainTextbox.rows / 2"\n\n");
refsTextbox.colsrows = mainTextbox.cols12;
refsTextbox.style.border = "none";
// Add to document
refsTextbox.style.lineHeight = "1.5em";
refsDiv.appendChild(refsH2);
refsTextbox.style.margin = "0";
refsDiv.appendChild(refsTextbox);
refsTextbox.style.resize = "vertical";
refsTextbox.style.width = "100%";
// Set up the submit handler (to integrate refs when done editing)
if(typeof editForm.onsubmit != "undefined") {
// Add to document
editForm.PsOnsubmit = editForm.onsubmit;
refsDiv.appendChild(refsH2);
}
refsDiv.appendChild(refsTextbox);
editForm.onsubmit = submitHandler;
// Set up the submit handler (to integrate refs when done editing)
// Don't submit form
window.addEventListener("submit", unloadHandler, false);
return false;
window.addEventListener("unload", unloadHandler, false);
unloadHandlerRegistered = true;
// Don't submit form
return false;
}
function convertButtonHandler() { // Called when script activated by button click
// Display warning
if(!window.confirm(messages.convertRefsWarning)) {
return false;
}
}
// Which group?
var group = window.prompt(messages.groupPrompt, "");
if(group === null) {
return false;
}
}
group = htmlUnquote(group.PsHTMLUnquote();
// The first button should disappear
if(refsButton.parentNode) {
refsButton.parentNode.removeChild(refsButton);
}
}
// Do the actual segregation work and save the random prefix
var segFormat = segregateRefs(mainTextbox.value, true, group, false);
if(!segFormat) {
return false;
}
}
randPrefix = segFormat.randPrefix;
// wikEd compatibility (frame -> textarea)
if(typeof wikEdUseWikEd != "undefined" && wikEdUseWikEd) {
WikEdUpdateTextarea();
}
}
// Update the textbox
mainTextbox.value = segFormat.wikiText;
clearUndoHistory(mainTextbox);
// wikEd compatibility (textarea -> frame)
// wikEd compatibility (textarea -> frame)
if(typeof wikEdUseWikEd != "undefined" && wikEdUseWikEd) {
if(typeof wikEdUseWikEd != "undefined" && wikEdUseWikEd) {
WikEdUpdateFrame();
WikEdUpdateFrame();
}
}
// Inline refs header
// Inline refs header
refsH2 = window.document.createElement("h2");
refsH2 = document.createElement("h2"); refsH2.appendChild(window.document.createTextNode(messages.convertHeader));
refsH2.style.borderColor = "silver";
// Inline refs textbox
refsH2.style.borderStyle = "solid";
if(!refsTextbox) {
refsH2.style.borderWidth = "1px 0";
// Does not exist; creating
refsH2.style.fontSize = "100%";
refsTextbox = window.document.createElement("textarea");
refsH2.style.fontWeight = "100%";
refsTextbox.id = "PsRefsTextbox";
refsH2.style.lineHeight = "normal";
refsTextbox.value = messages.refsCommentComplete +
refsH2.style.margin = "0";
segFormat.refCodes.join("\n");
refsH2.style.padding = "0.5em 0 0";
refsTextbox.rows = Math.floor(mainTextbox.rows / 2);
refsH2.style.textAlign = "center";
refsTextbox.cols = mainTextbox.cols;
// Inline refs textbox
// Add to document
if(!refsTextbox) {
refsDiv.appendChild(refsH2);
// Does not exist; creating
refsDiv.appendChild(refsTextbox);
refsTextbox = document.createElement("textarea");
} else {
refsTextbox.id = "PsRefsTextbox";
// Already exists
refsTextbox.value = messages.refsCommentComplete +
segFormat.refCodes.join("\n");
refsTextbox.rows = 12;
}
// Set a default edit summary.
window.document.getElementById("wpSummary").value = messages.convertSummary;
// Show the further instructions.
window.alert(messages.convertFurther);
// Don't submit form
return false;
}
refsTextbox.style.border = "none";
function loadHandler() { // This function is called on page load
refsTextbox.style.lineHeight = "1.5em";
try {
refsTextbox.style.margin = "0";
// Don't continue if the browser is Internet Explorer
refsTextbox.style.resize = "vertical";
if(window.navigator.appName == "Microsoft Internet Explorer") {
refsTextbox.style.width = "100%";
return;
}
// Add to document
refsDiv.appendChild(refsH2);
// Handle message translations
refsDiv.appendChild(refsTextbox);
messages = (typeof SegregateRefsJsL10n == "object" &&
} else {
typeof SegregateRefsJsL10n.version != "undefined" &&
// Already exists
SegregateRefsJsL10n.version == 1.11 ? SegregateRefsJsL10n :
refsTextbox.value = messages.refsCommentComplete +
SegregateRefsJsMsgs);
segFormat.refCodes.join("\n");
}
// Only activate on edit pages (that are not section edit pages)
if(!window.document.getElementById("editform") ||
// Set a default edit summary.
window.document.getElementById("editform").wpSection.value.length) {
document.getElementById("wpSummary").value = messages.convertSummary;
return;
}
// Show the further instructions.
window.alert(messages.convertFurther);
// Get the edit form
editForm = window.document.getElementById("editform");
// Don't submit form
// Get the edit box
return false;
mainTextbox = window.document.getElementById("wpTextbox1");
// Make the "segregate" button
refsButton = window.document.createElement("input");
refsButton.type = "button";
refsButton.value = messages.buttonText;
refsButton.setAttribute("style", messages.buttonStyle);
refsButton.onclick = refsButtonHandler;
// Make the "convert" button
convertButton = window.document.createElement("input");
convertButton.type = "button";
convertButton.value = messages.buttonConvertText;
convertButton.setAttribute("style", messages.buttonConvertStyle);
convertButton.onclick = convertButtonHandler;
if(typeof SegregateRefsJsAllowConversion == "undefined" ||
!SegregateRefsJsAllowConversion) {
convertButton.setAttribute("style", "display: none;");
}
// Add the refs div
refsDiv = window.document.createElement("div");
refsDiv.appendChild(refsButton);
refsDiv.appendChild(convertButton);
editForm.insertBefore(refsDiv,
window.document.getElementById("editpage-copywarn"));
} catch(e) {
}
}
// Register load handler
addOnloadHook(loadHandler);
$( function () {
} SegregateRefsJs();
try {
// Handle message translations
messages = (typeof SegregateRefsJsL10n == "object" &&
typeof SegregateRefsJsL10n.version != "undefined" &&
SegregateRefsJsL10n.version == 1.11 ? SegregateRefsJsL10n :
SegregateRefsJsMsgs);
// Only activate on edit pages (that are not section edit pages)
if(!document.getElementById("editform") ||
document.getElementById("editform").wpSection.value.length) {
return;
}
// Get the edit form
editForm = document.getElementById("editform");
// Get the edit box
mainTextbox = document.getElementById("wpTextbox1");
// Make the "segregate" button
refsButton = document.createElement("input");
refsButton.type = "button";
refsButton.value = messages.buttonText;
refsButton.setAttribute("style", messages.buttonStyle);
refsButton.onclick = refsButtonHandler;
// Make the "convert" button
convertButton = document.createElement("input");
convertButton.type = "button";
convertButton.value = messages.buttonConvertText;
convertButton.setAttribute("style", messages.buttonConvertStyle);
convertButton.onclick = convertButtonHandler;
if(typeof SegregateRefsJsAllowConversion == "undefined" ||
!SegregateRefsJsAllowConversion) {
convertButton.setAttribute("style", "display: none;");
}
// Add the refs div
refsDiv = document.createElement("div");
refsDiv.appendChild(refsButton);
refsDiv.appendChild(convertButton);
// Find position within the edit form to insert it at
var refsDivPos = mainTextbox, refsDivPosParent = refsDivPos.parentNode;
while (refsDivPosParent !== editForm) {
refsDivPos = refsDivPosParent;
refsDivPosParent = refsDivPos.parentNode;
if (!refsDivPosParent) {
refsDivPos = mainTextbox;
refsDivPosParent = refsDivPos.parentNode;
break;
}
}
refsDivPos = refsDivPos.nextSibling;
if (refsDivPos && refsDivPos.classList.contains("wikiEditor-ui-clear")) {
refsDivPos = refsDivPos.nextSibling;
}
refsDivPosParent.insertBefore(refsDiv, refsDivPos);
} catch(e) {
}
} );
})( jQuery );
// </nowiki></pre>
|