node.onclick = event || fuwRadioClick;
fuwAppendInput(option, node);
};
fuwMakeTextfield = function(label, event) {
var node = document.createElement('input');
node.type = 'text';
node.name = label;
node.size = fuwDefaultTextboxLength;
node.onchange = event || fuwUpdateOptions;
// only for testing:
//node.value = label;
fuwAppendInput(label, node);
};
fuwMakeTextarea = function(label, event) {
var node = document.createElement('textarea');
node.name = label;
node.rows = fuwDefaultTextareaLines;
node.style.width = fuwDefaultTextareaWidth;
node.onchange = event || fuwUpdateOptions;
//only for testing:
//node.innerHTML = label;
fuwAppendInput(label, node);
};
fuwMakeCheckbox = function(label, checked, event) {
var node = document.createElement('input');
node.name = label;
node.type = 'checkbox';
//only for testing:
//node.title= label;
node.checked = checked;
node.onchange = event || fuwUpdateOptions;
fuwAppendInput(label, node);
}
fuwMakeHiddenfield = function(name, value, id) {
var node = document.createElement('input');
node.name = name;
node.type = 'hidden';
node.value = value;
fuwAppendInput((id || name), node);
};
fuwMakeAnchor = function(label, href, content) {
var node = document.createElement('a');
node.name = label;
node.target= "_blank";
node.href = href;
node.innerHTML = content;
fuwAppendInput(label, node);
};
fuwMakeSelection = function(name, values) {
var root = document.createElement('select');
var current = root;
try {
for (i=0; i<values.length; i++) {
var line = values[i];
var entry;
if (line.length == 0) {
current = root;
}
else if (line.length == 1) {
entry = document.createElement('optgroup');
entry.setAttribute('label', line[0]);
root.appendChild(entry);
current = entry;
}
else {
entry = document.createElement('option');
entry.setAttribute('value', line[0]);
entry.setAttribute('title', '');
entry.innerHTML = line[1];
if (line.length > 2) {
entry.setAttribute('selected', 'selected');
}
current.appendChild(entry);
}
}
} catch (e) { alert("Name: " + name + ", i=" + i); }
root.name = name;
root.onchange = fuwUpdateOptions;
fuwAppendInput(name, root);
};
function fuwMakeWikilink(place, target, redlink, display) {  
place = fuwGet(place);
var id = place.id;
var anchor;
if (place.tagName == 'A') {
anchor = place;
}
else {
anchor = document.createElement('a');
place.appendChild(anchor);
}
anchor.href = mw.util.getUrl(target);
anchor.title = target;
anchor.innerHTML = target;
anchor.className = (redlink ? 'new' : null);
}  
function fuwAppendInput(label, content) {
// append a newly created input element to an existing
// span element marked as id="placeholderXYZ"
var node = fuwGet('placeholder' + label);
var old = fuwGet(label);
if (old) {
old.parentNode.removeChild(old);
}
content.id = content.id || label;
if (node) {
while (node.hasChildNodes) {
node.removeChild(node.firstChild);
}
node.appendChild(content);
}
}  
// ======================================================
// move an element away from its current position
// and append it to a target element if condition is true
// ======================================================
function fuwMove(mv, tg, condition, toStart) {
if (condition) {
move = fuwGet(mv);
target = fuwGet(tg);
if (move && target) {
var parent = move.parentNode;
if (! (target===parent)) {
parent.removeChild(move);
if (toStart) {
target.insertBefore(move, target.firstChild);
}
else {
target.appendChild(move);
}
}
}
else {
alert("Can't find elements: move=" + mv + "(" + move + "), target=" + tg + "(" + target + ")");
}
}
return condition;
}  
// ===================================================
// make an element visible/invisible
// ===================================================
function fuwSetVisible(tg, condition) {
target = fuwGet(tg);
if (target) {
if (condition) {
$(target).show;
}
else {
$(target).hide;
}
}
else {
alert("Element not found: " + ((!!tg && !!tg.nodeType) ? tg.id : tg));
}
}  
// ===================================================
// set enabled/disabled status for an element and/or
// all input controls contained in it.
// ===================================================
function fuwSetEnabled(tg, condition) {
target = fuwGet(tg);
try {
var elements = (target.tagName.match(/^(input|textarea|select|button|a)$/i) ?
[target] :
$('#' + target.id + ' *'));
for (i = 0; i<elements.length; i++) {
if (elements[i].tagName.match(/^(input|textarea|select|button|a)$/i)) {
elements[i].disabled = (condition ? null : "disabled");
}
}
} catch (e) { alert("Element not found: " + ((!!tg && !!tg.nodeType) ? tg.id : tg)); }
}  
// ===================================================
// convenience function to check whether a given
// element is currenly visible. Needs to check display
// property of the element and its ancestors
// ===================================================
function fuwIsVisible(el) {
element = fuwGet(el);
if (!element) return false;
el = element.id;  
var visible = true;
while (! (element === document.body)) {
if (element.style.display == "") {
visible = false;
break;
}
element = element.parentNode;
}
return visible;
}  
// ===================================================
// cleanup filename
// ===================================================
function fuwCleanFilename {
var nameBox = window.fuw.ScriptForm.InputName;
var oldname = name = $.trim(nameBox.value);  
if (name) {
// strip accidentally added or : brackets
name = name.replace(/(^\[\[:?)|(\]\]$)/g, "");
// strip accidentally added "File:" prefix
name = name.replace(/^(File|Image):/, "");
// replace underscores with spaces
name = name.replace(/_/g, " ");
// uppercase first letter
name = name[0].toUpperCase + name.slice(1);
}
if (oldname != name) {
nameBox.value = name;
}
// always return true so the next validation step will proceed:
return true;
}  
// ==================================================
// check filename for technically illegal
// characters, trying to fix them automatically
// ==================================================
function fuwCheckLegalFilename {
var nameBox = window.fuw.ScriptForm.InputName;
var oldname = name = $.trim(nameBox.value);  
if (name) {
// resolve accidentally entered html entities and URI-encoded %XX character codes
name = name.replace(/\&[a-z]+;/g, fuwHtmlEntityDecode);
name = name.replace(/(\%[A-F0-9]{2,2})/g, decodeURI);
// remove illegal characters # < > [ ] | { } /:
// using a best guess for an acceptable replacement
name = name.replace(/[<\[\{]/g, "(");
name = name.replace(/[>\]\}]/g, ")");
name = name.replace(/[#:\|]/g, ",");
name = name.replace(/\//g, "-");
// remove sequences of tildes
name = name.replace(/\~{3,}/g, "---");
// remove initial slash
name = name.replace(/^\//, "");
}  
if (oldname != name) {
window.fuw.warn.IllegalChars = true;
nameBox.value = name;
return false;
}
else {
window.fuw.warn.IllegalChars = false;
return true;
}
}
function fuwHtmlEntityDecode(str) {
// hack to translate accidentally entered html entity code
// into actual characters
var ta=document.createElement('textarea');
ta.innerHTML=str.replace(/</g,'&lt;').replace(/>/g,'&gt;');
return ta.value;
}  
// =======================================================
// Check against various common patterns of poorly chosen
// filenames (too short / too generic)
// =======================================================
function fuwCheckPoorFilename {
var nameBox = window.fuw.ScriptForm.InputName;
var name = $.trim(nameBox.value);
name = name.replace(/\.(png|gif|jpg|jpeg|xcf|pdf|mid|ogg|ogv|svg|djvu|tiff|tif|oga)$/i, "");  
// name should be at least 10 characters long, excluding file type extension
var tooShort = (name.length < 10);  
// common generic filename patterns:
// IMG......jpg
// Image....jpg
// DSC......jpg
// Picture......jpg
// Pic..........jpg
// anything that has fewer than 3 alphabetic letters and then just numbers
var pattern = /^(img|image|dsc|picture|pic)?(\\s*|\\_*|[a-z]{,3})?\\d+$/i;
var auto = name.match(pattern);  
window.fuw.warn.BadFilename = (tooShort || auto);