3675
правок
Mansur700 (обсуждение | вклад) (Полностью удалено содержимое страницы) Метка: очистка |
Mansur700 (обсуждение | вклад) Нет описания правки |
||
Строка 1: | Строка 1: | ||
// <nowiki> | |||
/* | |||
* =============================================================== | |||
* FileUploadWizard.js | |||
* Script for uploading files through a dynamic questionnaire. | |||
* This is the code to accompany [[Wikipedia:File Upload Wizard]]. | |||
* =============================================================== | |||
*/ | |||
var fuwTesting = false; | |||
var fuwDefaultTextboxLength = 60; | |||
var fuwDefaultTextareaWidth = '90%'; | |||
var fuwDefaultTextareaLines = 3; | |||
// ================================================================ | |||
// Constructor function of global fuw (= File Upload Wizard) object | |||
// ================================================================ | |||
function fuwGlobal() { | |||
// Loading the accompanying .css | |||
mw.loader.load( mw.config.get('wgServer') + mw.config.get('wgScriptPath') + | |||
'/index.php?title=MediaWiki:FileUploadWizard.css&action=raw&ctype=text/css', | |||
'text/css' ); | |||
// see if user is logged in, autoconfirmed, experienced etc. | |||
this.getUserStatus(); | |||
fuwSetVisible('warningLoggedOut', (this.userStatus == 'anon')); | |||
fuwSetVisible('warningNotConfirmed', (this.userStatus == 'notAutoconfirmed')); | |||
if ((this.userStatus == 'anon') || (this.userStatus == 'notAutoconfirmed')) { | |||
return; | |||
} | |||
fuwSetVisible('fuwStartScriptLink', false); | |||
// create the form element to wrap the main ScriptForm area | |||
// containing input elements of Step2 and Step3 | |||
var frm = fuwGet('fuwScriptForm'); | |||
if (! frm) { | |||
frm = document.createElement('form'); | |||
frm.id = "fuwScriptForm"; | |||
var area = fuwGet('placeholderScriptForm'); | |||
var parent = area.parentNode; | |||
parent.insertBefore(frm, area); | |||
parent.removeChild(area); | |||
frm.appendChild(area); | |||
} | |||
this.ScriptForm = frm; | |||
// create the TargetForm element that contains the filename | |||
// input box, together with hidden input controls. | |||
// This is the form that is actually submitted to the api.php. | |||
frm = fuwGet('TargetForm'); | |||
if (! frm) { | |||
frm = document.createElement('form'); | |||
frm.id = "TargetForm"; | |||
frm.method = "post"; | |||
frm.enctype = "multipart/form-data"; | |||
// "enctype" doesn't work properly on IE; need "encoding" instead: | |||
frm.encoding = "multipart/form-data"; | |||
// we'll submit via api.php, not index.php, mainly because that | |||
// allows us to use a proper edit summary different from the page content | |||
frm.action = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php'; | |||
// However, since api.php sends back a response page that humans won't want to read, | |||
// we'll have to channel that response away and discard it. We'll use a hidden iframe | |||
// for that purpose. | |||
// Unfortunately, it doesn't seem possible to submit file upload content through an | |||
// Xmlhtml object via Ajax. | |||
frm.target = "TargetIFrame"; | |||
//testing: | |||
//frm.target = "_blank"; | |||
var area = fuwGet('placeholderTargetForm'); | |||
var parent = area.parentNode; | |||
parent.insertBefore(frm, area); | |||
parent.removeChild(area); | |||
frm.appendChild(area); | |||
} | |||
this.TargetForm = frm; | |||
// For the testing version, create a third form that will display | |||
// the contents to be submitted, at the bottom of the page | |||
if (fuwTesting) { | |||
frm = fuwGet('fuwTestForm'); | |||
if (! frm) { | |||
frm = document.createElement('form'); | |||
frm.id = "fuwTestForm"; | |||
var area = fuwGet('placeholderTestForm'); | |||
var parent = area.parentNode; | |||
parent.insertBefore(frm, area); | |||
parent.removeChild(area); | |||
frm.appendChild(area); | |||
} | |||
this.TestForm = frm; | |||
} | |||
// objects to hold cached results during validation and processing | |||
this.opts = { }; | |||
this.warn = { }; | |||
// create the input filename box | |||
var filebox = document.createElement('input'); | |||
filebox.id = 'file'; | |||
filebox.name = 'file'; | |||
filebox.type = 'file'; | |||
filebox.size = fuwDefaultTextboxLength; | |||
filebox.onchange = fuwValidateFile; | |||
filebox.accept = 'image/png,image/jpeg,image/gif,image/svg+xml,image/tiff,image/x-xcf,application/pdf,image/vnd.djvu,audio/ogg,video/ogg,audio/rtp-midi'; | |||
fuwAppendInput('file', filebox); | |||
// create hidden controls for sending the remaining API parameters: | |||
fuwMakeHiddenfield('action', 'upload', 'apiAction'); | |||
fuwMakeHiddenfield('format', 'xml', 'apiFormat'); | |||
fuwMakeHiddenfield('filename', '', 'apiFilename'); | |||
fuwMakeHiddenfield('text', '', 'apiText'); | |||
fuwMakeHiddenfield('comment', '', 'apiComment'); | |||
fuwMakeHiddenfield('token', mw.user.tokens.get('csrfToken'), 'apiToken'); | |||
fuwMakeHiddenfield('ignorewarnings', 1, 'apiIgnorewarnings'); | |||
fuwMakeHiddenfield('watch', 1, 'apiWatch'); | |||
if (fuwTesting) { | |||
fuwMakeHiddenfield('title', mw.config.get('wgPageName') + "/sandbox", 'SandboxTitle'); | |||
fuwMakeHiddenfield('token', mw.user.tokens.get('csrfToken'), 'SandboxToken'); | |||
fuwMakeHiddenfield('recreate', 1, 'SandboxRecreate'); | |||
} | |||
// create a hidden IFrame to send the api.php response to | |||
var ifr = document.createElement('iframe'); | |||
ifr.id = "TargetIFrame"; | |||
ifr.name = "TargetIFrame"; | |||
//ifr.setAttribute('style', 'float:right;width:150px;height:150px;'); | |||
ifr.style.display = "none"; | |||
ifr.src = ""; | |||
fuwAppendInput('TargetIFrame', ifr); | |||
if (fuwTesting) { | |||
// create the sandbox submit button | |||
btn = document.createElement('input'); | |||
btn.id = 'SandboxButton'; | |||
btn.value = 'Sandbox'; | |||
btn.name = 'Sandbox'; | |||
btn.disabled = true; | |||
btn.type = 'button'; | |||
btn.style.width = '12em'; | |||
btn.onclick = fuwSubmitSandbox; | |||
fuwAppendInput('SandboxButton', btn); | |||
} | |||
// create the real submit button | |||
btn = document.createElement('input'); | |||
btn.id = "SubmitButton"; | |||
btn.value = "Upload"; | |||
btn.name = "Upload"; | |||
btn.disabled = true; | |||
btn.type = "button"; | |||
btn.onclick = fuwSubmitUpload; | |||
btn.style.width = '12em'; | |||
fuwAppendInput('SubmitButton', btn); | |||
// create the Commons submit button | |||
btn = document.createElement('input'); | |||
btn.id = "CommonsButton"; | |||
btn.value = "Upload on Commons"; | |||
btn.name = "Upload_on_Commons"; | |||
btn.disabled = true; | |||
btn.type = "button"; | |||
btn.onclick = fuwSubmitCommons; | |||
btn.style.width = '12em'; | |||
fuwAppendInput('CommonsButton', btn); | |||
// create reset buttons | |||
for (i = 1; i<=2; i++) { | |||
btn = document.createElement('input'); | |||
btn.id = 'ResetButton' + i; | |||
btn.value = "Reset form"; | |||
btn.name = "Reset form"; | |||
btn.type = "button"; | |||
btn.onclick = fuwReset; | |||
btn.style.width = '12em'; | |||
fuwAppendInput('ResetButton' + i, btn); | |||
} | |||
// names of radio button fields | |||
var optionRadioButtons = { | |||
// top-level copyright status choice | |||
'FreeOrNonFree' : ['OptionFree','OptionNonFree','OptionNoGood'], | |||
// main subsections under OptionFree | |||
'FreeOptions' : ['OptionOwnWork', 'OptionThirdParty', 'OptionFreeWebsite', | |||
'OptionPDOld', 'OptionPDOther'], | |||
// main subsections under OptionNonFree | |||
'NonFreeOptions': ['OptionNFSubject','OptionNF3D','OptionNFExcerpt', | |||
'OptionNFCover','OptionNFLogo','OptionNFPortrait', | |||
'OptionNFMisc'], | |||
// response options inside warningFileExists | |||
'FileExistsOptions': | |||
['NoOverwrite','OverwriteSame','OverwriteDifferent'], | |||
// choice of evidence in OptionThirdParty subsection | |||
'ThirdPartyEvidenceOptions' : | |||
['ThirdPartyEvidenceOptionLink', | |||
'ThirdPartyEvidenceOptionOTRS', | |||
'ThirdPartyEvidenceOptionOTRSForthcoming', | |||
'ThirdPartyEvidenceOptionNone'], | |||
// choice of PD status in OptionPDOld subsection | |||
'PDOldOptions' : ['PDUS1923','PDURAA','PDFormality','PDOldOther'], | |||
// choice of PD status in OptionPDOther subsection | |||
'PDOtherOptions': ['PDOtherUSGov','PDOtherOfficial','PDOtherSimple', | |||
'PDOtherOther'], | |||
// whether target article is wholly or only partly dedicated to discussing non-free work: | |||
'NFSubjectCheck': ['NFSubjectCheckDedicated','NFSubjectCheckDiscussed'], | |||
'NF3DCheck' : ['NF3DCheckDedicated','NF3DCheckDiscussed'], | |||
// choice about copyright status of photograph in OptionNF3D | |||
'NF3DOptions' : ['NF3DOptionFree','NF3DOptionSame'] | |||
}; | |||
for (var group in optionRadioButtons) { | |||
var op = optionRadioButtons[group]; | |||
for (i=0; i<op.length; i++) { | |||
fuwMakeRadiobutton(group, op[i]); | |||
} | |||
} | |||
this.ScriptForm.NoOverwrite.checked = true; | |||
// input fields that trigger special | |||
// onchange() event handlers for validation: | |||
fuwMakeTextfield('InputName', fuwValidateFilename); | |||
fuwMakeTextfield('NFArticle', fuwValidateNFArticle); | |||
// names of input fields that trigger normal | |||
// validation event handler | |||
var activeTextfields = [ | |||
'Artist3D','Country3D', | |||
'Date','OwnWorkCreation','OwnWorkPublication', | |||
'Author','Source', | |||
'Permission','ThirdPartyOtherLicense', | |||
'ThirdPartyEvidenceLink','ThirdPartyOTRSTicket', | |||
'FreeWebsiteOtherLicense', | |||
'PDOldAuthorLifetime','Publication', | |||
'PDOldCountry','PDOldPermission', | |||
'PDOfficialPermission','PDOtherPermission', | |||
'NFSubjectPurpose', 'NF3DOrigDate', 'NF3DPurpose', | |||
'NF3DCreator', | |||
'NFPortraitDeceased', | |||
'EditSummary' | |||
]; | |||
for (i=0; i<activeTextfields.length; i++) { | |||
fuwMakeTextfield(activeTextfields[i]); | |||
} | |||
// names of multiline textareas | |||
var activeTextareas = [ | |||
'InputDesc','NF3DPermission', | |||
'NFCommercial','NFPurpose','NFReplaceableText', | |||
'NFReplaceable','NFCommercial','NFMinimality','AnyOther' | |||
]; | |||
for (i=0; i<activeTextareas.length; i++) { | |||
fuwMakeTextarea(activeTextareas[i]); | |||
}; | |||
var checkboxes = [ | |||
'NFCoverCheckDedicated','NFLogoCheckDedicated','NFPortraitCheckDedicated' | |||
]; | |||
for (i=0; i<checkboxes.length; i++) { | |||
fuwMakeCheckbox(checkboxes[i]); | |||
}; | |||
var licenseLists = { | |||
'OwnWorkLicense' : | |||
// array structure as expected for input to fuwMakeSelection() function. | |||
// any entry that is a two-element array will be turned into an option | |||
// (first element is the value, second element is the display string). | |||
// Entries that are one-element arrays will be the label of an option group. | |||
// Zero-element arrays mark the end of an option group. | |||
[ | |||
['Allow all use as long as others credit you and share it under similar conditions'], | |||
['self|GFDL|cc-by-sa-3.0|migration=redundant', | |||
'Creative Commons Attribution-Share Alike 3.0 + GFDL (recommended)', | |||
true], | |||
['self|cc-by-sa-3.0', | |||
'Creative Commons Attribution-Share Alike 3.0'], | |||
[], | |||
['Allow all use as long as others credit you'], | |||
['self|cc-by-3.0', | |||
'Creative Commons Attribution 3.0'], | |||
[], | |||
['Reserve no rights'], | |||
['cc-zero', | |||
'CC-zero Universal Public Domain Dedication'], | |||
[] | |||
], | |||
'ThirdPartyLicense' : | |||
[ | |||
['', 'please select the correct license...'], | |||
['Freely licensed:'], | |||
['cc-by-sa-3.0', 'Creative Commons Attribution-Share Alike (cc-by-sa-3.0)'], | |||
['cc-by-3.0', 'Creative Commons Attribution (cc-by-3.0)'], | |||
['GFDL', 'GNU Free Documentation License (GFDL)'], | |||
[], | |||
['No rights reserved:'], | |||
['PD-author', 'Public domain'], | |||
[], | |||
['Other (see below)'], | |||
[] | |||
], | |||
'FreeWebsiteLicense' : | |||
[ | |||
['', 'please select the correct license...'], | |||
['Freely licensed:'], | |||
['cc-by-sa-3.0', 'Creative Commons Attribution-Share Alike (cc-by-sa-3.0)'], | |||
['cc-by-3.0', 'Creative Commons Attribution (cc-by-3.0)'], | |||
['GFDL', 'GNU Free Documentation License (GFDL)'], | |||
[], | |||
['No rights reserved:'], | |||
['PD-author', 'Public domain'], | |||
[], | |||
['Other (see below)'], | |||
[] | |||
], | |||
'USGovLicense' : | |||
[ | |||
['PD-USGov', 'US Federal Government'], | |||
['PD-USGov-NASA','NASA'], | |||
['PD-USGov-Military-Navy','US Navy'], | |||
['PD-USGov-NOAA','US National Oceanic and Atmospheric Administration'], | |||
['PD-USGov-Military-Air_Force','US Air Force'], | |||
['PD-USGov-Military-Army','US Army'], | |||
['PD-USGov-CIA-WF','CIA World Factbook'], | |||
['PD-USGov-USGS','United States Geological Survey'] | |||
], | |||
'IneligibleLicense' : | |||
[ | |||
['', 'please select one...'], | |||
['PD-shape','Item consists solely of simple geometric shapes'], | |||
['PD-text','Item consists solely of a few individual words or letters'], | |||
['PD-textlogo','Logo or similar item consisting solely of letters and simple geometric shapes'], | |||
['PD-chem','Chemical structural formula'], | |||
['PD-ineligible','Other kind of item that contains no original authorship'] | |||
], | |||
'NFSubjectLicense' : | |||
[ | |||
['', 'please select one...'], | |||
['Non-free 2D art', '2-dimensional artwork (painting, drawing etc.)'], | |||
['Non-free historic image', 'Unique historic photograph'], | |||
['Non-free fair use in', 'something else (please describe in description field on top)'] | |||
], | |||
'NF3DLicense' : | |||
[ | |||
['', 'please select one...'], | |||
['Non-free architectural work', 'Architectural work'], | |||
['Non-free 3D art', 'Other 3-dimensional creative work (sculpture etc.)'] | |||
], | |||
'NFCoverLicense' : | |||
[ | |||
['', 'please select one...'], | |||
['Non-free book cover', 'Cover page of a book'], | |||
['Non-free album cover', 'Cover of a sound recording (album, single, song, CD)'], | |||
['Non-free game cover', 'Cover of a video/computer game'], | |||
['Non-free magazine cover', 'Cover page of a magazine'], | |||
['Non-free video cover', 'Cover of a video'], | |||
['Non-free software cover', 'Cover of a software product'], | |||
['Non-free product cover', 'Cover of some commercial product'], | |||
['Non-free title-card', 'Title screen of a TV programme'], | |||
['Non-free movie poster', 'Movie poster'], | |||
['Non-free poster', 'Official poster of an event'], | |||
['Non-free fair use in', 'something else (please describe in description field on top)'] | |||
], | |||
'NFExcerptLicense' : | |||
[ | |||
['', 'please select one...'], | |||
['Non-free television screenshot', 'Television screenshot'], | |||
['Non-free film screenshot', 'Movie screenshot'], | |||
['Non-free game screenshot', 'Game screenshot'], | |||
['Non-free video screenshot', 'Video screenshot'], | |||
['Non-free music video screenshot', 'Music video screenshot'], | |||
['Non-free software screenshot', 'Software screenshot'], | |||
['Non-free web screenshot', 'Website screenshot'], | |||
['Non-free speech', 'Audio excerpt from a speech'], | |||
['Non-free audio sample', 'Sound sample of an audio recording'], | |||
['Non-free video sample', 'Sample extract from a video'], | |||
['Non-free sheet music', 'Sheet music representing a musical piece'], | |||
['Non-free comic', 'Panel from a comic, graphic novel, manga etc.'], | |||
['Non-free computer icon', 'Computer icon'], | |||
['Non-free newspaper image', 'Page from a newspaper'], | |||
['Non-free fair use in', 'something else (please describe in description field on top)'] | |||
], | |||
'NFLogoLicense' : | |||
[ | |||
['Non-free logo', 'Logo of a company, organization etc.'], | |||
['Non-free seal', 'Official seal, coat of arms etc'], | |||
['Non-free symbol', 'Other official symbol'] | |||
], | |||
'NFMiscLicense' : | |||
[ | |||
['Non-free fair use in', 'something else (please describe in description field on top)'], | |||
['Non-free historic image', 'Historic photograph'], | |||
['Non-free 2D art', '2-dimensional artwork (painting, drawing etc.)'], | |||
['Non-free currency', 'Depiction of currency (banknotes, coins etc.)'], | |||
['Non-free architectural work', 'Architectural work'], | |||
['Non-free 3D art', 'Other 3-dimensional creative work (sculpture etc.)'], | |||
['Non-free book cover', 'Cover page of a book'], | |||
['Non-free album cover', 'Cover of a sound recording(album, single, song, CD)'], | |||
['Non-free game cover', 'Cover of a video/computer game'], | |||
['Non-free magazine cover', 'Cover page of a magazine'], | |||
['Non-free video cover', 'Cover of a video'], | |||
['Non-free software cover', 'Cover of a software product'], | |||
['Non-free product cover', 'Cover of some commercial product'], | |||
['Non-free title-card', 'Title screen of a TV programme'], | |||
['Non-free movie poster', 'Movie poster'], | |||
['Non-free poster', 'Official poster of an event'], | |||
['Non-free television screenshot', 'Television screenshot'], | |||
['Non-free film screenshot', 'Movie screenshot'], | |||
['Non-free game screenshot', 'Game screenshot'], | |||
['Non-free video screenshot', 'Video screenshot'], | |||
['Non-free music video screenshot', 'Music video screenshot'], | |||
['Non-free software screenshot', 'Software screenshot'], | |||
['Non-free web screenshot', 'Website screenshot'], | |||
['Non-free speech', 'Audio excerpt from a speech'], | |||
['Non-free audio sample', 'Sound sample of an audio recording'], | |||
['Non-free video sample', 'Sample extract from a video'], | |||
['Non-free sheet music', 'Sheet music representing a musical piece'], | |||
['Non-free comic', 'Panel from a comic, graphic novel, manga etc.'], | |||
['Non-free computer icon', 'Computer icon'], | |||
['Non-free newspaper image', 'Page from a newspaper'], | |||
['Non-free logo', 'Logo of a company, organization etc.'], | |||
['Non-free seal', 'Official seal, coat of arms etc'], | |||
['Non-free symbol', 'Other official symbol'], | |||
['Non-free sports uniform', 'Sports uniform'], | |||
['Non-free stamp', 'Stamp'] | |||
], | |||
'NFExtraLicense' : | |||
[ | |||
['', 'none'], | |||
['Crown copyright and other governmental sources'], | |||
['Non-free Crown copyright', 'UK Crown Copyright'], | |||
['Non-free New Zealand Crown Copyright', 'NZ Crown Copyright'], | |||
['Non-free Canadian Crown Copyright', 'Canadian Crown Copyright'], | |||
['Non-free AUSPIC', 'AUSPIC (Australian Parliament image database'], | |||
['Non-free Philippines government', 'Philippines government'], | |||
['Non-free Finnish Defence Forces', 'Finnish Defence Forces'], | |||
[], | |||
['Other individual sources'], | |||
['Non-free Denver Public Library', 'Denver Public Library'], | |||
['Non-free ESA media', 'ESA (European Space Agency)'], | |||
[], | |||
['Possibly public domain in other countries'], | |||
['Non-free Old-50', 'Author died more than 50 years ago.'], | |||
['Non-free Old-70', 'Author died more than 70 years ago.'], | |||
[], | |||
['Some permissions granted, but not completely free'], | |||
['Non-free promotional', 'From promotional press kit'], | |||
['Non-free with NC', 'Permission granted, but only for educational and/or non-commercial purposes'], | |||
['Non-free with ND', 'Permission granted, but no derivative works allowed'], | |||
['Non-free with permission', 'Permission granted, but only for Wikipedia'], | |||
[] | |||
] | |||
}; | |||
for (var group in licenseLists) { | |||
fuwMakeSelection(group, licenseLists[group]); | |||
} | |||
this.knownCommonsLicenses = { | |||
'self|GFDL|cc-by-sa-all|migration=redundant' : 1, | |||
'self|Cc-zero' : 1, | |||
'PD-self' : 1, | |||
'self|GFDL|cc-by-sa-3.0|migration=redundant' : 1, | |||
'self|GFDL|cc-by-3.0|migration=redundant' : 1, | |||
'self|cc-by-sa-3.0' : 1, | |||
'cc-by-sa-3.0' : 1, | |||
'cc-by-sa-2.5' : 1, | |||
'cc-by-3.0' : 1, | |||
'cc-by-2.5' : 1, | |||
'FAL' : 1, | |||
'PD-old-100' : 1, | |||
'PD-old' : 1, | |||
'PD-Art' : 1, | |||
'PD-US' : 1, | |||
'PD-USGov' : 1, | |||
'PD-USGov-NASA' : 1, | |||
'PD-USGov-Military-Navy' : 1, | |||
'PD-ineligible' : 1, | |||
'Attribution' : 1, | |||
'Copyrighted free use' : 1 | |||
}; | |||
// textfields that don't react directly | |||
// to user input and are used only for assembling stuff: | |||
if (fuwTesting) { | |||
fuwMakeTextfield('SandboxSummary', function(){void(0);}); | |||
fuwMakeTextarea('SandboxText', function(){void(0);}); | |||
fuwGet('SandboxSummary').disabled="disabled"; | |||
fuwGet('SandboxText').disabled="disabled"; | |||
fuwGet('SandboxText').rows = 12; | |||
} | |||
// set links to "_blank" target, so we don't accidentally leave the page, | |||
// because on some browsers that would destroy all the input the user has already entered | |||
$('.fuwOutLink a').each(function() { | |||
this.target = '_blank'; | |||
}); | |||
// make main area visible | |||
fuwSetVisible('UploadScriptArea', true); | |||
} | |||
// ====================================== | |||
// end of fuwGlobal constructor function | |||
// ====================================== | |||
function fuwRadioClick(e) { | |||
var ev = e || event; | |||
var src = ev.target || ev.srcElement; | |||
//alert('onclick event from ' + src + ' (' + src.value + ')'); | |||
fuwUpdateOptions(); | |||
return true; | |||
} | |||
/* | |||
* ============================================================= | |||
* function fuwUpdateOptions | |||
* ============================================================= | |||
* This is the onchange event handler for most of the input | |||
* elements in the main form. It changes visibility and disabled | |||
* status for the various sections of the input form in response | |||
* to which options are chosen. | |||
*/ | |||
function fuwUpdateOptions() { | |||
var fuw = window.fuw; | |||
var warn = fuw.warn; | |||
var opts = fuw.opts = { }; | |||
opts.InputFilename = $('#TargetForm input#file').val(); | |||
var widgets = fuw.ScriptForm.elements; | |||
for (i = 0; i < widgets.length; i++) { | |||
var w = widgets[i]; | |||
if (w.type == "radio") { | |||
var nm = w.name; | |||
var id = w.id; | |||
var vl = w.checked && !w.disabled && fuwIsVisible(w); | |||
opts[id] = vl; | |||
if (vl) opts[nm] = id; | |||
} | |||
else { | |||
var id = w.id; | |||
var active = !w.disabled && fuwIsVisible(w); | |||
if (active) { | |||
var value = ((type == 'checkbox') ? w.checked : w.value); | |||
opts[id] = value; | |||
} | |||
} | |||
}; | |||
opts.MainOption = opts.FreeOptions || opts.NonFreeOptions; | |||
// some parts of the input form are re-used across sections | |||
// and must be moved into the currently active input section: | |||
// minimality section is shared between all NF sections | |||
fuwMove('NFMinimalitySection', 'detailsNFSubject', (opts.OptionNFSubject)) || | |||
fuwMove('NFMinimalitySection', 'detailsNF3D', (opts.OptionNF3D)) || | |||
fuwMove('NFMinimalitySection', 'detailsNFExcerpt', (opts.OptionNFExcerpt)) || | |||
fuwMove('NFMinimalitySection', 'detailsNFCover', (opts.OptionNFCover)) || | |||
fuwMove('NFMinimalitySection', 'detailsNFLogo', (opts.OptionNFLogo)) || | |||
fuwMove('NFMinimalitySection', 'detailsNFPortrait', (opts.OptionNFPortrait)) || | |||
fuwMove('NFMinimalitySection', 'detailsNFMisc', true); | |||
// AnyOtherInfo section is shared between all | |||
fuwMove('AnyOtherInfo', 'detailsOwnWork', opts.OptionOwnWork) || | |||
fuwMove('AnyOtherInfo', 'detailsThirdParty', opts.OptionThirdParty) || | |||
fuwMove('AnyOtherInfo', 'detailsFreeWebsite', opts.OptionFreeWebsite) || | |||
fuwMove('AnyOtherInfo', 'detailsPDOld', opts.OptionPDOld) || | |||
fuwMove('AnyOtherInfo', 'detailsPDOther', opts.OptionPDOther) || | |||
fuwMove('AnyOtherInfo', 'detailsNFSubject', opts.OptionNFSubject) || | |||
fuwMove('AnyOtherInfo', 'detailsNF3D', opts.OptionNF3D) || | |||
fuwMove('AnyOtherInfo', 'detailsNFExcerpt', opts.OptionNFExcerpt) || | |||
fuwMove('AnyOtherInfo', 'detailsNFCover', opts.OptionNFCover) || | |||
fuwMove('AnyOtherInfo', 'detailsNFLogo', opts.OptionNFLogo) || | |||
fuwMove('AnyOtherInfo', 'detailsNFPortrait', opts.OptionNFPortrait) || | |||
fuwMove('AnyOtherInfo', 'detailsNFMisc', opts.OptionNFMisc); | |||
// author input field is shared between all sections except "Own Work". | |||
// (will serve for the immediate/photographic author, in those cases where there | |||
// are two author fields) | |||
fuwMove('Author', 'placeholderFreeWebsiteAuthor', (opts.OptionFreeWebsite)) || | |||
fuwMove('Author', 'placeholderPDOldAuthor', (opts.OptionPDOld)) || | |||
fuwMove('Author', 'placeholderPDOtherAuthor', (opts.OptionPDOther)) || | |||
fuwMove('Author', 'placeholderNFSubjectAuthor', (opts.OptionNFSubject)) || | |||
fuwMove('Author', 'placeholderNF3DAuthor', (opts.OptionNF3D)) || | |||
fuwMove('Author', 'placeholderNFExcerptAuthor', (opts.OptionNFExcerpt)) || | |||
fuwMove('Author', 'placeholderNFCoverAuthor', (opts.OptionNFCover)) || | |||
fuwMove('Author', 'placeholderNFPortraitAuthor', (opts.OptionNFPortrait)) || | |||
fuwMove('Author', 'placeholderNFMiscAuthor', (opts.OptionNFMisc)) || | |||
fuwMove('Author', 'placeholderAuthor', true); | |||
// source input field is shared between all sections except "Own Work". | |||
// (will serve for immediate/web source, in those cases where there are two | |||
// source fields involved) | |||
fuwMove('Source', 'placeholderFreeWebsiteSource', (opts.OptionFreeWebsite)) || | |||
fuwMove('Source', 'placeholderPDOldSource', (opts.OptionPDOld)) || | |||
fuwMove('Source', 'placeholderPDOtherSource', (opts.OptionPDOther)) || | |||
fuwMove('Source', 'placeholderNFSubjectSource', (opts.OptionNFSubject)) || | |||
fuwMove('Source', 'placeholderNF3DSource', (opts.OptionNF3D)) || | |||
fuwMove('Source', 'placeholderNFExcerptSource', (opts.OptionNFExcerpt)) || | |||
fuwMove('Source', 'placeholderNFCoverSource', (opts.OptionNFCover)) || | |||
fuwMove('Source', 'placeholderNFLogoSource', (opts.OptionNFLogo)) || | |||
fuwMove('Source', 'placeholderNFPortraitSource', (opts.OptionNFPortrait)) || | |||
fuwMove('Source', 'placeholderNFMiscSource', (opts.OptionNFMisc)) || | |||
fuwMove('Source', 'placeholderSource', true); | |||
// date input field is shared between all sections except "Logo", which doesn't need it. | |||
// will serve for derived/photographic date in the case of 3D items | |||
fuwMove('Date', 'placeholderFreeWebsiteDate', (opts.OptionFreeWebsite)) || | |||
fuwMove('Date', 'placeholderThirdPartyDate', (opts.OptionThirdParty)) || | |||
fuwMove('Date', 'placeholderPDOldDate', (opts.OptionPDOld)) || | |||
fuwMove('Date', 'placeholderPDOtherDate', (opts.OptionPDOther)) || | |||
fuwMove('Date', 'placeholderNFSubjectDate', (opts.OptionNFSubject)) || | |||
fuwMove('Date', 'placeholderNF3DDate', (opts.OptionNF3D)) || | |||
fuwMove('Date', 'placeholderNFExcerptDate', (opts.OptionNFExcerpt)) || | |||
fuwMove('Date', 'placeholderNFCoverDate', (opts.OptionNFCover)) || | |||
fuwMove('Date', 'placeholderNFPortraitDate', (opts.OptionNFPortrait)) || | |||
fuwMove('Date', 'placeholderNFMiscDate', (opts.OptionNFMisc)) || | |||
fuwMove('Date', 'placeholderDate', true); | |||
// permission field is shared between ThirdParty and FreeWebsite sections | |||
fuwMove('Permission', 'placeholderFreeWebsitePermission', (opts.OptionFreeWebsite)) || | |||
fuwMove('Permission', 'placeholderPermission', true); | |||
// publication field is shared between PDOld, NFPortrait and NFMisc | |||
fuwMove('Publication', 'placeholderNFPortraitPublication', (opts.OptionNFPortrait)) || | |||
fuwMove('Publication', 'placeholderNFMiscPublication', (opts.OptionNFMisc)) || | |||
fuwMove('Publication', 'placeholderPublication', true); | |||
// Purpose, Commercial, Replaceable and ReplaceableText FUR fields are shared | |||
// between some but not all of the non-free sections | |||
fuwMove('NFPurpose', 'placeholderNFExcerptPurpose', (opts.OptionNFExcerpt)) || | |||
fuwMove('NFPurpose', 'placeholderNFPurpose'); | |||
fuwMove('NFCommercial', 'placeholderNFPortraitCommercial', (opts.OptionNFPortrait)) || | |||
fuwMove('NFCommercial', 'placeholderNFCommercial'); | |||
fuwMove('NFReplaceable', 'placeholderNFPortraitReplaceable', (opts.OptionNFPortrait)) || | |||
fuwMove('NFReplaceable', 'placeholderNFReplaceable'); | |||
fuwMove('NFReplaceableText', 'placeholderNFExcerptReplaceable', (opts.OptionNFExcerpt)) || | |||
fuwMove('NFReplaceableText', 'placeholderNFReplaceableText', true); | |||
// submit button goes to Step1 if user has chosen a plain overwrite of an existing file, | |||
// and to the active section of Step3 if otherwise | |||
fuwMove('fuwSubmit', 'UploadScriptStep1', (warn.ImageExists && opts.OverwriteSame)) || | |||
fuwMove('fuwSubmit', 'detailsOwnWork', opts.OptionOwnWork) || | |||
fuwMove('fuwSubmit', 'detailsThirdParty', opts.OptionThirdParty) || | |||
fuwMove('fuwSubmit', 'detailsFreeWebsite', opts.OptionFreeWebsite) || | |||
fuwMove('fuwSubmit', 'detailsPDOld', opts.OptionPDOld) || | |||
fuwMove('fuwSubmit', 'detailsPDOther', opts.OptionPDOther) || | |||
fuwMove('fuwSubmit', 'detailsNFSubject', opts.OptionNFSubject) || | |||
fuwMove('fuwSubmit', 'detailsNF3D', opts.OptionNF3D) || | |||
fuwMove('fuwSubmit', 'detailsNFExcerpt', opts.OptionNFExcerpt) || | |||
fuwMove('fuwSubmit', 'detailsNFCover', opts.OptionNFCover) || | |||
fuwMove('fuwSubmit', 'detailsNFLogo', opts.OptionNFLogo) || | |||
fuwMove('fuwSubmit', 'detailsNFPortrait', opts.OptionNFPortrait) || | |||
fuwMove('fuwSubmit', 'fuwSubmitHost', true); | |||
// Show and hide warnings: | |||
// filename-related warnings: | |||
fuwSetVisible('warningIllegalChars', warn.IllegalChars); | |||
fuwSetVisible('warningBadFilename', warn.BadFilename); | |||
fuwSetVisible('warningImageOnCommons', warn.ImageOnCommons); | |||
fuwSetVisible('warningImageExists', warn.ImageExists); | |||
fuwMove('warningImageThumb', 'warningImageOnCommons', warn.ImageOnCommons, true) || | |||
fuwMove('warningImageThumb', 'warningImageExists', true, true); | |||
// notices related to the top-level options: | |||
fuwSetVisible('warningWhyNotCommons', opts.OptionFree); | |||
fuwSetVisible('warningNF', opts.OptionNonFree); | |||
fuwSetVisible('warningNoGood', opts.OptionNoGood); | |||
// warnings related to non-free "used in" article | |||
fuwSetVisible('warningNFArticleNotFound', warn.NFArticleNotFound); | |||
fuwSetVisible('warningNFArticleNotMainspace', warn.NFArticleNotMainspace); | |||
fuwSetVisible('warningUserspaceDraft', warn.UserspaceDraft); | |||
fuwSetVisible('warningNFArticleDab', warn.NFArticleDab); | |||
fuwSetVisible('NFArticleOK', warn.NFArticleOK); | |||
// warnings depending on user status: | |||
if (fuw.userStatus.match(/problem|newbie|notAutoconfirmed/)) { | |||
fuwSetVisible('warningFreeWebsite', opts.OptionFreeWebsite); | |||
fuwSetVisible('warningOwnWork', opts.OptionOwnWork); | |||
fuwSetVisible('warningPDOther', opts.OptionPDOther); | |||
fuwSetVisible('warningNFSubject', opts.OptionNFSubject); | |||
} | |||
// hide main sections in case of intended plain overwrite: | |||
fuwSetVisible('UploadScriptStep2', !(warn.ImageExists && opts.OverwriteSame)); | |||
fuwSetVisible('UploadScriptStep3', !(warn.ImageExists && opts.OverwriteSame)); | |||
// show/hide top-level options | |||
fuwSetVisible('detailsFreeStatus', opts.OptionFree); | |||
fuwSetVisible('sendToCommons', opts.OptionFree); | |||
// show/hide details sections | |||
fuwSetVisible('detailsNFArticle', opts.OptionNonFree); | |||
fuwSetVisible('detailsNFWorkType', opts.OptionNonFree); | |||
fuwSetVisible('detailsOwnWork', opts.OptionOwnWork); | |||
fuwSetVisible('detailsThirdParty', opts.OptionThirdParty); | |||
fuwSetVisible('detailsFreeWebsite', opts.OptionFreeWebsite); | |||
fuwSetVisible('detailsPDOld', opts.OptionPDOld); | |||
fuwSetVisible('detailsPDOther', opts.OptionPDOther); | |||
fuwSetVisible('detailsNFSubject', opts.OptionNFSubject); | |||
fuwSetVisible('detailsNF3D', opts.OptionNF3D); | |||
fuwSetVisible('detailsNFExcerpt', opts.OptionNFExcerpt); | |||
fuwSetVisible('detailsNFCover', opts.OptionNFCover); | |||
fuwSetVisible('detailsNFLogo', opts.OptionNFLogo); | |||
fuwSetVisible('detailsNFPortrait', opts.OptionNFPortrait); | |||
fuwSetVisible('detailsNFMisc', opts.OptionNFMisc); | |||
fuwSetVisible('EditSummaryDiv', opts.OverwriteSame || opts.OverwriteDifferent); | |||
// set enabled/disabled | |||
// It might be useful to adapt this to be more liberal about | |||
// the order of input, at least for experienced users. | |||
//fuwSetEnabled('Artist3D', opts.PD3D); | |||
//fuwSetEnabled('Country3D', opts.FOP3D); | |||
fuwSetEnabled('ThirdPartyEvidenceLink', opts.ThirdPartyEvidenceOptionLink); | |||
fuwSetEnabled('ThirdPartyOTRSTicket', opts.ThirdPartyEvidenceOptionOTRS); | |||
fuwSetEnabled('NFSubjectPurpose', opts.NFSubjectCheckDiscussed); | |||
fuwSetEnabled('NF3DPurpose', opts.NF3DCheckDiscussed); | |||
fuwSetEnabled('NF3DPermission', opts.NF3DOptionFree); | |||
fuwSetEnabled('USGovLicense', opts.PDOtherUSGov); | |||
fuwSetEnabled('PDOfficialPermission', opts.PDOtherOfficial); | |||
fuwSetEnabled('IneligibleLicense', opts.PDOtherSimple); | |||
fuwSetEnabled('PDOtherPermission', opts.PDOtherOther); | |||
fuwSetEnabled('AnyOther', true); | |||
// need to re-collect the remaining (non-radiobutton) input into the opts object again, | |||
// preparing for validation: | |||
for (i = 0; i < widgets.length; i++) { | |||
var w = widgets[i]; | |||
var type = w.type; | |||
if (type != "radio") { | |||
var id = w.id; | |||
var active = !w.disabled && fuwIsVisible(w); | |||
if (active) { | |||
var value = ((type == 'checkbox') ? w.checked : w.value); | |||
opts[id] = value; | |||
} | |||
} | |||
}; | |||
// final step of validation: check if input is sufficient for | |||
// setting the submit buttons active | |||
var valid = fuw.validateInput(); | |||
var validForCommons = valid && opts.OptionFree && !(opts.OverwriteSame || opts.OverwriteDifferent) | |||
&& !opts.ThirdPartyEvidenceOptionNone; | |||
fuwSetVisible('sendToCommons', opts.OptionFree); | |||
fuwSetEnabled('CommonsButton', validForCommons); | |||
fuwGet('fuwSubmitText').innerHTML = opts.OptionFree ? | |||
("<b>No</b>, I want to upload this file here on this wiki only.<br/>" + | |||
"<small>This way it can be used only on the English Wikipedia. However, somebody " + | |||
"else might still decide to copy it to Commons or use it elsewhere later. If you " + | |||
"do not want your file to be copied to Commons and deleted locally, consider adding " + | |||
"{{tl|Keep local}}.</small>") : | |||
"Upload this file."; | |||
fuwGet('SubmitButton').value = validForCommons ? "Upload locally" : "Upload"; | |||
fuwSetEnabled('EditSummary', true); | |||
fuwSetEnabled('SubmitButton', valid && (fuw.userStatus != 'notAutoconfirmed')); | |||
if (fuwTesting) { | |||
fuwSetEnabled('SandboxButton', valid); | |||
} | |||
// if we're in testing mode, update the Sandbox display fields | |||
// after each input change. In normal mode, collectInput() will | |||
// only be needed on submit. | |||
if (fuwTesting) { | |||
fuw.collectInput(); | |||
fuw.formatOutput(false); | |||
fuwSetVisible('placeholderTestForm', true); | |||
} | |||
} | |||
// ============================================================ | |||
// methods of the global fuw object | |||
// ============================================================ | |||
// ============================================================ | |||
// report validation status of filename information | |||
// ============================================================ | |||
// This is called from within fuw.validateInput(), i.e. every | |||
// time anything in the whole form is changed. It only reports | |||
// results that have previously been cached in the opts and warn | |||
// objects. The actual checking is done in the event handler | |||
// of the file input boxes. | |||
fuwGlobal.prototype.hasValidFilename = function() { | |||
var opts = this.opts; | |||
var warn = this.warn; | |||
var valid = | |||
opts.InputName && | |||
opts.InputFilename && | |||
!warn.BadFilename && | |||
!warn.ImageOnCommons && | |||
// if image exists on enwiki, accept only if user has confirmed overwrite: | |||
!(warn.ImageExists && !(opts.OverwriteSame || opts.OverwriteDifferent)); | |||
//alert("HasValidFilename: " + valid); | |||
return valid; | |||
}; | |||
// ============================================================ | |||
// validation status for common input elements for all free | |||
// options | |||
// ============================================================ | |||
fuwGlobal.prototype.hasValidCommonFreeInput = function() { | |||
var opts = this.opts; | |||
var warn = this.warn; | |||
var valid = opts.InputDesc; | |||
//alert("HasValidCommonFreeInput: " + valid); | |||
return valid; | |||
}; | |||
// ============================================================ | |||
// validation status for common input elements for all non-free | |||
// options | |||
// ============================================================ | |||
fuwGlobal.prototype.hasValidCommonNFInput = function() { | |||
var opts = this.opts; | |||
var warn = this.warn; | |||
var valid = | |||
opts.OptionNonFree && | |||
opts.InputDesc && | |||
opts.NFArticle && | |||
opts.Source && | |||
opts.NFMinimality && | |||
!warn.NFArticleNotFound && | |||
!warn.NFArticleNotMainspace && | |||
!warn.NFArticleDab; | |||
//alert("hasValidCommonNFInput: " + valid); | |||
return valid; | |||
}; | |||
// ============================================================ | |||
// Main validation routine. Modify this to tweak which fields | |||
// are to be considered obligatory for each case group | |||
// ============================================================ | |||
fuwGlobal.prototype.validateInput = function() { | |||
var opts = this.opts; | |||
var warn = this.warn; | |||
var valid = ( | |||
this.hasValidFilename() | |||
&& | |||
(! (opts.OverwriteDifferent && ! opts.EditSummary)) | |||
&& | |||
( | |||
( // overwriting is okay if there is an edit summary | |||
opts.OverwriteSame && opts.EditSummary | |||
) | |||
|| | |||
( // free options | |||
this.hasValidCommonFreeInput() && | |||
( | |||
(opts.OptionOwnWork && | |||
opts.Date && | |||
opts.OwnWorkLicense) | |||
|| | |||
(opts.OptionThirdParty && | |||
opts.Author && | |||
opts.Source && | |||
opts.Permission && | |||
(opts.ThirdPartyOtherLicense || opts.ThirdPartyLicense) && | |||
((opts.ThirdPartyEvidenceOptionLink && opts.ThirdPartyEvidenceLink) || | |||
opts.ThirdPartyEvidenceOptionOTRS || | |||
opts.ThirdPartyEvidenceOptionOTRSForthcoming || | |||
opts.ThirdPartyEvidenceOptionNone)) | |||
|| | |||
(opts.OptionFreeWebsite && | |||
opts.Author && | |||
opts.Source && | |||
(opts.FreeWebsiteOtherLicense || opts.FreeWebsiteLicense) && | |||
opts.Permission) | |||
|| | |||
(opts.OptionPDOld && | |||
opts.Author && | |||
opts.PDOldAuthorLifetime && | |||
opts.Publication && | |||
opts.Date && | |||
opts.Source && | |||
opts.PDOldOptions && | |||
(! (opts.PDOldOther && ! opts.PDOldPermission))) | |||
|| | |||
(opts.OptionPDOther && | |||
opts.Author && | |||
opts.Source && | |||
((opts.PDOtherUSGov && opts.USGovLicense) || | |||
(opts.PDOtherOfficial && opts.PDOfficialPermission) || | |||
(opts.PDOtherSimple && opts.IneligibleLicense) || | |||
(opts.PDOtherOther && opts.PDOtherPermission))) | |||
) | |||
) // end of free options | |||
|| | |||
( // non-free options | |||
this.hasValidCommonNFInput() && | |||
( | |||
(opts.OptionNFSubject && | |||
opts.NFSubjectLicense && | |||
opts.Author && | |||
(opts.NFSubjectCheckDedicated || | |||
(opts.NFSubjectCheckDiscussed && opts.NFSubjectPurpose))) | |||
|| | |||
(opts.OptionNF3D && | |||
opts.NF3DLicense && | |||
opts.NF3DCreator && | |||
opts.Author && | |||
(opts.NF3DOptionSame || | |||
(opts.NF3DOptionFree || opts.NF3DPermission)) && | |||
(opts.NF3DCheckDedicated || | |||
(opts.NF3DCheckDiscussed && opts.NF3DPurpose))) | |||
|| | |||
(opts.OptionNFExcerpt && | |||
opts.NFExcerptLicense && | |||
opts.Author && | |||
opts.NFPurpose) | |||
|| | |||
(opts.OptionNFCover && | |||
opts.NFCoverLicense && | |||
opts.Author && | |||
opts.NFCoverCheckDedicated | |||
) | |||
|| | |||
(opts.OptionNFLogo && | |||
opts.NFLogoLicense && | |||
opts.NFLogoCheckDedicated | |||
) | |||
|| | |||
(opts.OptionNFPortrait && | |||
opts.Publication && | |||
opts.NFPortraitDeceased && | |||
opts.Author && | |||
opts.NFPortraitCheckDedicated && | |||
opts.NFReplaceable && | |||
opts.NFCommercial) | |||
|| | |||
(opts.OptionNFMisc && | |||
opts.NFMiscLicense && | |||
opts.Author && | |||
opts.Publication && | |||
opts.NFPurpose && | |||
opts.NFReplaceableText && | |||
opts.NFReplaceable && | |||
opts.NFCommercial) | |||
) | |||
) // end of non-free options | |||
) | |||
); | |||
return valid; | |||
}; | |||
// ============================================================= | |||
// return which template name will be used as the main | |||
// description template | |||
// ============================================================= | |||
fuwGlobal.prototype.getDescriptionTemplateName = function() { | |||
// standard "Information" template for free files: | |||
if (this.opts.OptionFree) return "Information"; | |||
// experimental new version of fair-use rationale template, | |||
// designed to fit the fields used in the wizard | |||
else if (this.opts.OptionNonFree) return "Non-free use rationale 2"; | |||
return undefined; | |||
}; | |||
// ============================================================= | |||
// get the license tag code from the appropriate input element | |||
// ============================================================= | |||
fuwGlobal.prototype.getStandardLicense = function() { | |||
var opts = this.opts; | |||
} | |||
fuwGlobal.prototype.getLicense = function() { | |||
var opts = this.opts; | |||
// ThirdParty and FreeWebsite have alternative input fields | |||
// for manual entry of other licenses: | |||
var license = {}; | |||
if (opts.PDOtherOther || opts.PDOldOther) { | |||
license.special = opts.PDOtherOther ? opts.PDOtherPermission : opts.PDOldPermission; | |||
if (! (license.special.match(/^\s*\{\{.+\}\}\s*$/))) { | |||
license.special = '{{PD-because|' + license.special + '}}'; | |||
} | |||
} | |||
else { | |||
license.special = | |||
opts.ThirdPartyOtherLicense || | |||
opts.FreeWebsiteOtherLicense || | |||
(opts.PDOtherOfficial ? ('{{PD-because|official item legally exempt from copyright in its country of origin}}') : null) || | |||
(opts.OptionNFPortrait ? ('{{Non-free biog-pic|' + opts.NFArticle + '}}') : null); | |||
} | |||
if (! license.special) { | |||
// standard, non-parametrized tag licenses from dropdownbox. | |||
var simpleLicense = (opts.OptionOwnWork ? opts.OwnWorkLicense : null) || | |||
(opts.OptionThirdParty ? opts.ThirdPartyLicense : null) || | |||
(opts.OptionFreeWebsite ? opts.FreeWebsiteLicense : null) || | |||
(opts.OptionNFSubject ? opts.NFSubjectLicense : null) || | |||
(opts.OptionNF3D ? opts.NF3DLicense : null) || | |||
(opts.OptionNFExcerpt ? opts.NFExcerptLicense : null) || | |||
(opts.OptionNFCover ? opts.NFCoverLicense : null) || | |||
(opts.OptionNFLogo ? opts.NFLogoLicense : null) || | |||
(opts.OptionNFMisc ? opts.NFMiscLicense : null) || | |||
(opts.PDOtherUSGov ? opts.USGovLicense : null) || | |||
(opts.PDOtherSimple ? opts.IneligibleLicense : null) || | |||
(opts.PDUS1923 ? 'PD-US-1923' : null) || | |||
(opts.PDURAA ? 'PD-URAA' : null) || | |||
(opts.PDFormality ? 'PD-US' : null); | |||
// "PD-author" needs parameter, at least on Commons | |||
if (simpleLicense == 'PD-author') { | |||
license.special = '{{PD-author|' + opts.Author + '}}'; | |||
} | |||
else if (this.knownCommonsLicenses[simpleLicense]) { | |||
// make sure we send only those licenses as "standard" licenses | |||
// that exist in the Commons license dropdown box | |||
license.standard = simpleLicense; | |||
} | |||
else { | |||
license.special = '\{\{' + simpleLicense + '\}\}'; | |||
} | |||
} | |||
return license; | |||
}; | |||
function fuwSubst(template) { | |||
return '{{subst:' + template + '}}'; | |||
} | |||
// =================================================================== | |||
// Produce code for local tracking categories | |||
// =================================================================== | |||
fuwGlobal.prototype.getTrackingCategory = function() { | |||
var opts = this.opts; | |||
var cat = ""; | |||
if (opts.OptionFreeWebsite) { cat = "Files from freely licensed external sources"; } | |||
else if (opts.OptionThirdParty) { cat = "Files licensed by third parties"; } | |||
else if (opts.PDOtherOther || opts.PDOldOther) { cat = "Files with non-standard public domain statements"; } | |||
else if (opts.OptionNFSubject || opts.OptionNF3D) { cat = "Non-free files uploaded as object of commentary"; } | |||
if (cat) { | |||
cat = "\n\{\{Category ordered by date|" + cat + "|" + | |||
fuwSubst("CURRENTYEAR") + "|" + fuwSubst("CURRENTMONTH") + "|" + fuwSubst("CURRENTDAY2") + "\}\}"; | |||
} | |||
return cat; | |||
}; | |||
// =================================================================== | |||
// Get or create an edit summary for the upload | |||
// =================================================================== | |||
// Note: if we work with the api.php interface, we can have separate | |||
// data for the edit summary and the description page, which is far | |||
// better than the way the index.php interface does it. | |||
// TO DO: need to actually define an input element for a manually | |||
// entered edit summary. Must be obligatory when overwriting files. | |||
// In other cases we'll use an automatic edit summary. | |||
// =================================================================== | |||
fuwGlobal.prototype.getEditSummary = function() { | |||
var opts = this.opts; | |||
return ( | |||
(opts.EditSummary ? (opts.EditSummary + ' ([[' + mw.config.get('wgPageName') + '|File Upload Wizard]])') : null)|| | |||
("Uploading " + | |||
( | |||
(opts.OptionOwnWork ? 'a self-made file ' : false) || | |||
(opts.OptionThirdParty ? 'a free file from somebody else ' : false) || | |||
(opts.OptionFreeWebsite ? 'a file from a free published source ' : false) || | |||
(opts.OptionPDOld ? 'an old public-domain work ' : false) || | |||
(opts.OptionPDOther ? 'a public-domain item ' : false) || | |||
(opts.OptionNFSubject ? 'a non-free work, as object of commentary ' : false) || | |||
(opts.OptionNF3D ? 'a depiction of a non-free 3D artwork ' : false) || | |||
(opts.OptionNFExcerpt ? 'an excerpt from a non-free work ' : false) || | |||
(opts.OptionNFCover ? 'a piece of non-free cover art ' : false) || | |||
(opts.OptionNFLogo ? 'a non-free logo ' : false) || | |||
(opts.OptionNFPortrait ? 'a non-free historic portrait ' : false) || | |||
(opts.OptionNFMisc ? 'a non-free file ' : "") | |||
) | |||
+ | |||
("using [[" + mw.config.get('wgPageName') + "|File Upload Wizard]]") | |||
)); | |||
}; | |||
function fuwPackInfo(text, forCommons) { | |||
if (forCommons) { | |||
// reformat wikilinks embedded in description fields to adapt them for Commons | |||
text = text.replace(/\[\[([^\]]+)\]\]/g, | |||
function(str, p1, offset, s) { | |||
// mark File links as local | |||
if (p1.match(/^:(File|Image):/)) { | |||
return "[[:en" + p1 + "]]"; | |||
} | |||
// leave prefixed links unchanged: | |||
else if (p1.match(/^:[\w\-]+:/)) { | |||
return str; | |||
} | |||
// if the link is piped, add a prefix only | |||
else if (p1.match(/.+\|/)) { | |||
return "[[:en:" + p1 + "]]"; | |||
} | |||
// introduce a pipe | |||
else { | |||
return "[[:en:" + p1 + "|" + p1 + "]]"; | |||
} | |||
} | |||
); | |||
return "{{en|" + text + "}}"; | |||
} else return text; | |||
} | |||
// ================================================================ | |||
// This is the main method called by the event handler for the | |||
// (experimental) submit button. Its main task is to collect the | |||
// input into a single string of wikitext for the description page. | |||
// ================================================================ | |||
fuwGlobal.prototype.collectInput = function() { | |||
var opts = this.opts; | |||
// object representing template fields for filling in | |||
// the description template. Pre-loaded with some | |||
// standard settings: | |||
var descFields = this.descFields = { | |||
'Description' : opts.InputDesc, | |||
'Author' : opts.Author, | |||
'Date' : opts.Date, | |||
'Source' : opts.Source | |||
}; | |||
// "other information" (outside the template) | |||
this.otherInfo = null; | |||
if (opts.OptionNonFree) { | |||
descFields.Article = opts.NFArticle; | |||
} | |||
// add/modify option-specific fields: | |||
switch (opts.MainOption) { | |||
case 'OptionOwnWork': | |||
// use standard "source" field for optional "how created?" and | |||
// "previously published" input fields. | |||
descFields.Source = fuwAppendLines([ | |||
(opts.OwnWorkCreation || "{{own}}"), | |||
"<br/>\n", | |||
fuwSurroundString("'''Previously published:''' ", opts.OwnWorkPublication)]); | |||
var username = mw.user.getName(); | |||
descFields.Author = '[[User:' + username + '|' + username + ']]'; | |||
break; | |||
case 'OptionThirdParty': | |||
// use standard "permission" field for a compilation of the | |||
// "permission" input field and the various "evidence" options | |||
var evidence = ( | |||
opts.ThirdPartyEvidenceOptionLink ? | |||
("The license statement can be found online at: " + opts.ThirdPartyEvidenceLink) : | |||
(opts.ThirdPartyEvidenceOptionOTRS ? | |||
("The license agreement has been forwarded to OTRS." + | |||
fuwSurroundString(" Ticket: ", opts.ThirdPartyOTRSTicket) + "\{\{OTRS pending|year=" + fuwSubst("CURRENTYEAR") + | |||
"|month=" + fuwSubst("CURRENTMONTH") + | |||
"|day=" + fuwSubst("CURRENTDAY2") + "\}\}") : | |||
(opts.ThirdPartyEvidenceOptionOTRSForthcoming ? | |||
"The license agreement will be forwarded to OTRS shortly. \{\{OTRS pending|year=" + fuwSubst("CURRENTYEAR") + | |||
"|month=" + fuwSubst("CURRENTMONTH") + | |||
"|day=" + fuwSubst("CURRENTDAY2") + "\}\}" : | |||
(opts.ThirdPartyEvidenceOptionNone ? | |||
"Will be provided on request." : null)))); | |||
descFields.Permission = fuwAppendLines([ | |||
opts.ThirdPartyPermission, | |||
"<br/>\n", | |||
fuwSurroundString("'''Evidence:''' ", evidence)]); | |||
break; | |||
case 'OptionFreeWebsite': | |||
descFields.Permission = opts.Permission; | |||
break; | |||
case 'OptionPDOld': | |||
// add "lifetime" input to "author" field | |||
descFields.Author = fuwAppendLines([ | |||
opts.Author, | |||
"<br/>\n", | |||
fuwSurroundString("(Life time: ", opts.PDOldAuthorLifetime, ")") | |||
]); | |||
// combine original and direct source into standard "source" field: | |||
descFields.Source = fuwAppendLines([ | |||
fuwSurroundString("'''Original publication''': ", opts.Publication), | |||
"<br/>\n", | |||
fuwSurroundString("'''Immediate source''': ", opts.Source) | |||
]); | |||
// no standard tag available for "lack-of-registration" PD-US. Need | |||
// to put this into the "permission" field | |||
if (opts.PDFormality) | |||
descFields.Permission = | |||
"Copyright expired because the work was published without a copyright " + | |||
"notice and/or without the necessary copyright registration."; | |||
// add optional "explanation" input to "permission" field | |||
if (opts.PDOldPermission) { | |||
descFields.Permission = fuwAppendLines([ | |||
descFields.Permission, | |||
"\n\n", | |||
opts.PDOldPermission | |||
]); | |||
} | |||
break; | |||
case 'OptionPDOther': | |||
// Need "permission" field in case of "official item" option | |||
if (opts.PDOtherOfficial) | |||
descFields.Permission = opts.PDOfficialPermission; | |||
break; | |||
case 'OptionNFSubject': | |||
// most FUR elements can be automatically provided: | |||
descFields.Purpose = ( | |||
opts.NFSubjectCheckDedicated ? | |||
("For visual identification of the object of the article. " + | |||
"The article as a whole is dedicated specifically to a discussion of this work.") : | |||
(opts.NFSubjectCheckDiscussed ? | |||
("To support encyclopedic discussion of this work in this article. " + | |||
"The illustration is specifically needed to support the following point(s): " + | |||
"<br/>\n" + opts.NFSubjectPurpose) : null) | |||
); | |||
// I hate FURs filled with trivial/predictable/redundant verbiage, | |||
// so we'll just cut it short. And don't anybody dare complain that | |||
// that's not a valid FUR. | |||
descFields.Replaceability = "n.a."; | |||
descFields.Commercial = "n.a."; | |||
break; | |||
case 'OptionNF3D': | |||
// complex case: we need to assemble attribution and FUR both for the | |||
// original 3D work and for the photographic depiction. Both might be | |||
// non-free. | |||
descFields.Author = fuwAppendLines([ | |||
fuwSurroundString("'''Original work:''' ", opts.NF3DCreator), | |||
"<br/>\n", | |||
fuwSurroundString("'''Depiction:''' ", opts.Author) | |||
]); | |||
descFields.Date = fuwAppendLines([ | |||
fuwSurroundString("'''Original work:''' ", opts.NF3DOrigDate), | |||
"<br/>\n", | |||
fuwSurroundString("'''Depiction:''' ", opts.Date) | |||
]); | |||
descFields.Purpose = ( | |||
opts.NF3DCheckDedicated ? | |||
("For visual identification of the object of the article. " + | |||
"The article as a whole is dedicated specifically to a discussion of this work.") : | |||
(opts.NF3DCheckDiscussed ? | |||
("To support encyclopedic discussion of this work in this article. " + | |||
"The illustration is specifically needed to support the following point(s): " + | |||
"<br/>\n" + opts.NF3DPurpose) : null) | |||
); | |||
descFields.Replaceability = "n.a."; | |||
descFields.Commercial = "n.a."; | |||
descFields["Other information"] = ( | |||
opts.NF3DOptionSame ? | |||
("The image was created and published by the same author who also " + | |||
"holds the rights to the original object, and no alternative depiction " + | |||
"could be suitably created.") : | |||
("The author of the image has released the photographic work under a " + | |||
"free license, or it is in the public domain: " + opts.NF3DPermission) | |||
); | |||
break; | |||
case 'OptionNFExcerpt': | |||
// FURs for screenshots etc. don't normally need to bother | |||
// about replaceability (with free images) and with commercial role, | |||
// but do need to bother about purpose and about replaceability with text. | |||
descFields.Purpose = opts.NFPurpose; | |||
descFields.Replaceability_text = opts.NFReplaceableText; | |||
descFields.Replaceability = "n.a."; | |||
descFields.Commercial = "n.a."; | |||
break; | |||
case 'OptionNFCover': | |||
// cover art gets standard rationales. | |||
descFields.Purpose = | |||
"to serve as the primary means of visual identification " + | |||
"at the top of the article dedicated to the work in question."; | |||
descFields.Replaceability = "n.a."; | |||
descFields.Commercial = "n.a."; | |||
break; | |||
case 'OptionNFLogo': | |||
// logos get standard rationales. | |||
descFields.Purpose = | |||
"to serve as the primary means of visual identification " + | |||
"at the top of the article dedicated to the entity in question."; | |||
descFields.Replaceability = "n.a."; | |||
descFields.Commercial = "n.a."; | |||
break; | |||
case 'OptionNFPortrait': | |||
// as with other historic photographs, it is useful to have both | |||
// original publication and direct source | |||
descFields.Source = fuwAppendLines([ | |||
fuwSurroundString("'''Original publication''': ", opts.Publication), | |||
"<br/>\n", | |||
fuwSurroundString("'''Immediate source''': ", opts.Source) | |||
]); | |||
descFields.Purpose = | |||
"for visual identification of the person in question, " + | |||
"at the top of his/her biographical article"; | |||
descFields.Replaceability = opts.NFReplaceable; | |||
descFields.Commercial = opts.NFCommercial; | |||
descFields['Other information'] = | |||
"The subject of the photograph has been deceased since: " + opts.NFPortraitDeceased; | |||
break; | |||
case 'OptionNFMisc': | |||
descFields.Source = fuwAppendLines([ | |||
fuwSurroundString( | |||
"'''Original publication''': ", | |||
opts.Publication, | |||
"<br/>\n'''Immediate source:''' "), | |||
"", | |||
opts.Source | |||
]); | |||
descFields.Purpose = opts.NFPurpose; | |||
descFields.Replaceability = opts.NFReplaceable; | |||
descFields.Replaceability_text = opts.NFReplaceable_text; | |||
descFields.Commercial = opts.NFCommercial; | |||
break; | |||
}; | |||
if (opts.OptionNonFree) { | |||
// common stuff for all non-free files: | |||
// Minimality field (same for all NF options): | |||
descFields.Minimality = opts.NFMinimality; | |||
// append optional "extra license" selector and "AnyOther" fields | |||
// to "Other information" field: | |||
descFields['Other information'] = fuwAppendLines([ | |||
descFields['Other information'], | |||
"<br/>\n", | |||
fuwSurroundString('\{\{', opts.NFExtraLicense, '\}\}'), | |||
"<br/>\n", | |||
opts.AnyOther | |||
]); | |||
} | |||
else { | |||
// common stuff for all free files: | |||
descFields.Other_versions = '' | |||
this.otherInfo = fuwAppendLines([this.otherInfo, "\n\n", opts.AnyOther]); | |||
} | |||
}; | |||
fuwGlobal.prototype.formatOutput = function(forCommons) { | |||
var baseForm = this.ScriptForm; | |||
var targetForm = this.TargetForm; | |||
if (fuwTesting) { | |||
var testForm = this.TestForm; | |||
} | |||
var opts = this.opts; | |||
var otherInfo = this.otherInfo; | |||
var descFields = this.descFields; | |||
var summary = "{{" + this.getDescriptionTemplateName(); | |||
// assemble all fields into the wikitext of the description page: | |||
var fieldOrder = [ | |||
'Source', 'Date', 'Author', 'Permission', 'Other_versions', | |||
'Article', 'Purpose', 'Replaceability', 'Replaceability_text', | |||
'Minimality', 'Commercial', 'Other information' | |||
]; | |||
summary += "\n|Description = " + fuwPackInfo(descFields['Description'], forCommons); | |||
for (var i = 0; i < fieldOrder.length; i++) { | |||
if (descFields[fieldOrder[i]]) { | |||
summary += "\n|" + fieldOrder[i] + " = " + descFields[fieldOrder[i]]; | |||
} | |||
} | |||
summary += "\n}}\n"; | |||
if (otherInfo) { | |||
summary += "\n;Other information:\n" + fuwPackInfo(otherInfo, forCommons) + "\n"; | |||
} | |||
var editSummary = this.getEditSummary(); | |||
var license = this.getLicense(); | |||
if (forCommons) { | |||
// pack our description info into an url pointing to the | |||
// standard Commons Special:Upload | |||
// with pre-loaded description fields | |||
summary = fuwSubst("Upload marker added by en.wp UW") + "\n" + summary; | |||
summary = summary.replace(/\{\{OTRS pending\}\}/g, fuwSubst("OP")); | |||
if (license.special) { | |||
// manually format the whole description page including the license tag, if it | |||
// isn't one of the bare standard licenses in the dropdown box. Otherwise, | |||
// submit description summary and license as two separate url parameters. | |||
summary = summary + "\n\n" + license.special; | |||
} | |||
return ('https://commons.wikimedia.org/w/index.php' + | |||
"?title=Special:Upload" + | |||
"&wpUploadDescription=" + | |||
encodeURIComponent(summary) + | |||
(license.standard ? | |||
("&wpLicense=" + encodeURIComponent(license.standard)) : '') + | |||
"&wpDestFile=" + | |||
encodeURIComponent(opts.InputName)); | |||
} | |||
else { | |||
// pack all description into a single "text" parameter to be submitted | |||
// to the local api.php upload. | |||
summary = "==Summary==\n" + | |||
summary + | |||
"\n==Licensing==\n" + | |||
(license.standard ? ("\{\{" + license.standard + "\}\}") : license.special) + | |||
this.getTrackingCategory(); | |||
if (fuwTesting) { | |||
// Testing mode: show our data in the dummy form | |||
// at the bottom of the page. | |||
fuwGet('placeholderSandboxFilename').innerHTML = opts.InputName; | |||
this.TestForm.SandboxSummary.value = editSummary; | |||
this.TestForm.SandboxText.value = summary; | |||
fuwSetVisible('placeholderTestForm', true); | |||
} | |||
// write output parameters into target form | |||
// I can't believe IE7 is too stupid to simply understand "this.TargetForm.filename.value". | |||
($('#TargetForm [name="filename"]')[0]).value = opts.InputName; | |||
($('#TargetForm [name="text"]' )[0]).value = summary; | |||
($('#TargetForm [name="comment"]' )[0]).value = editSummary; | |||
($('#TargetForm [name="token"]' )[0]).value = mw.user.tokens.get('csrfToken'); | |||
} | |||
}; | |||
function fuwHasUserGroup(group) { | |||
// workaround because old IE versions don't have array.indexOf :-( | |||
for (i = 0; i < mw.config.get('wgUserGroups').length; i++) { | |||
if (mw.config.get('wgUserGroups')[i] == group) { | |||
return true; | |||
} | |||
} | |||
return false | |||
} | |||
fuwGlobal.prototype.getUserStatus = function() { | |||
// function to determine the experience status and userrights of the current user: | |||
// 'anon': not logged in; can't use script. | |||
// 'notAutoconfirmed': can't use local upload, but may use script to prepare upload for Commons | |||
// 'newbie': autoconfirmed but editcount < 100 | |||
// (may be used in future to adapt instructions more to newbie needs) | |||
// 'problem': autoconfirmed but has 3 or more image-related warnings or deletion notifications among recent user talk entries | |||
// (may be used in future to produce more strongly worded instructions) | |||
// 'autoconfirmed': regular user | |||
// 'sysop' | |||
if (mw.config.get('wgUserName')) { | |||
if (fuwHasUserGroup('sysop')) { | |||
this.userStatus = 'sysop'; | |||
} | |||
else if (fuwHasUserGroup('autoconfirmed') || fuwHasUserGroup('confirmed')) { | |||
this.userStatus = 'autoconfirmed'; | |||
$.ajax({ | |||
url : mw.util.wikiScript( 'api' ), | |||
type : 'GET', | |||
dataType: 'xml', | |||
traditional : true, | |||
data: { | |||
format: 'xml', | |||
action: 'query', | |||
meta : 'userinfo', | |||
uiprop: 'editcount', | |||
prop : 'revisions', | |||
titles: 'User talk' + mw.config.get('wgUserName'), | |||
rvprop: 'comment|user', | |||
rvlimit: 30 | |||
}, | |||
success: function(data) { | |||
// callback func | |||
var fuw = window.fuw; | |||
if (data) { | |||
var ui = data.getElementsByTagName('userinfo'); | |||
if (ui) { | |||
var editcount = ui[0].getAttribute('editcount'); | |||
if (editcount < 100) { | |||
fuw.userStatus = 'newbie'; | |||
} | |||
} | |||
var revs = data.getElementsByTagName('rev'); | |||
var countWarn = 0; | |||
for (i = 0; i < revs.length; i++) { | |||
var rev = revs[i]; | |||
var usr = rev.getAttribute('user'); | |||
var cmt = rev.getAttribute('comment'); | |||
if ((usr == 'ImageTaggingBot') || | |||
(cmt.search(/(tagging for deletion of \[\[File)|(Uploading files missing)|(File (source and )?copyright licensing problem)|(Speedy deletion nomination of \[\[File)|(Notification: listing at \[\[possibly unfree files)/) >= 0)) { | |||
countWarn += 1; | |||
} | |||
} | |||
if (countWarn >= 3) { | |||
fuw.userStatus = 'problem'; | |||
} | |||
} | |||
} | |||
}); | |||
} | |||
else { | |||
this.userStatus = 'notAutoconfirmed'; | |||
} | |||
} | |||
else { | |||
this.userStatus = 'anon'; | |||
} | |||
}; | |||
// ================================================================== | |||
// functions for building form elements | |||
// ================================================================== | |||
fuwMakeRadiobutton = function(group, option, checked, event) { | |||
// Stupid IE7 doesn't get "value" attribute unless it's created in this convoluted way. | |||
// Annoying. | |||
var node = $('<input type="radio" id="' + option + '" name="' + group + '" value="' + option + '"></input>')[0]; | |||
if (checked) node.checked = true; | |||
node.onclick = event || fuwRadioClick; | |||
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', '{{' + line[0] + '}}'); | |||
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 == "none") { | |||
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,'<').replace(/>/g,'>'); | |||
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); | |||
return !tooShort && !auto; | |||
} | |||
// ======================================================= | |||
// check if file extensions match between local filename | |||
// and target filename input box. Automatically append | |||
// appropriate extension to target filename if they don't. | |||
// ======================================================= | |||
function fuwCheckFileExtension() { | |||
var nameBox = window.fuw.ScriptForm.InputName; | |||
var name = $.trim(nameBox.value); | |||
var fileBox = window.fuw.TargetForm.file; | |||
var file = fileBox.value; | |||
// cancel check if no filename has been provided yet | |||
if (!file || !name) return true; | |||
var extensions = /.+\.(png|gif|jpg|jpeg|xcf|pdf|mid|ogg|ogv|svg|djvu|tiff|tif|oga)$/i; | |||
var mimetypes = { | |||
"png" : "image/png", | |||
"gif" : "image/gif", | |||
"jpg" : "image/jpeg", | |||
"jpeg" : "image/jpeg", | |||
"xcf" : "image/x-xcf", | |||
"pdf" : "application/pdf", | |||
"mid" : "audio/rtp-midi", | |||
"ogg" : "audio/ogg", | |||
"ogv" : "video/ogg", | |||
"svg" : "image/svg+xml", | |||
"djvu" : "image/vnd.djvu", | |||
"tiff" : "image/tiff", | |||
"tif" : "image/tiff", | |||
"oga" : "video/ogg" | |||
}; | |||
var found = extensions.exec(file); | |||
var fileExt = found ? found[1].toLowerCase() : ""; | |||
found = extensions.exec(name); | |||
var nameExt = found ? found[1].toLowerCase() : ""; | |||
var mime = mimetypes[fileExt]; | |||
if (fileExt && mime && (mimetypes[nameExt] != mime)) { | |||
nameBox.value = name.replace(/\.?$/, ('.' + fileExt)); | |||
} | |||
return true; | |||
} | |||
// ============================================================ | |||
// Check if a file under the chosen name already exists, | |||
// either locally or on Commons. | |||
// Store results in the fuw.warn object, so warnings will | |||
// be displayed on the next fuwUpdateOptions() call | |||
// ============================================================ | |||
function fuwCheckFileExists() { | |||
// this is an asynchronous AJAX function. | |||
// results won't yet be present when this function returns. | |||
var nameBox = window.fuw.ScriptForm.InputName; | |||
var name = $.trim(nameBox.value); | |||
// using the jQuery wrapper for the Ajax functionality: | |||
$.ajax({ | |||
url : mw.util.wikiScript( 'api' ), | |||
type : 'GET', | |||
dataType: 'xml', | |||
traditional : true, | |||
data: { | |||
format: 'xml', | |||
action: 'query', | |||
titles: 'File:' + name, | |||
prop : 'imageinfo', | |||
iiprop: 'url|user', | |||
iiurlwidth: 120 | |||
}, | |||
success: function(resp) { | |||
// callback function, called when API query has succeeded: | |||
// see if the request has returned info from an existing image: | |||
var foundlist = resp.getElementsByTagName('ii'); | |||
var exists = (foundlist.length >= 1); | |||
var isCommons = false; | |||
if (exists) { | |||
// extract description data from http response. | |||
// see https://www.mediawiki.org/wiki/API:Properties#imageinfo_.2F_ii | |||
// for structure of API response | |||
var foundImg = foundlist[0]; | |||
isCommons = (foundImg.parentNode.parentNode.getAttribute('imagerepository')=='shared'); | |||
// need this data for creating our own image thumb link | |||
var width = foundImg.getAttribute('thumbwidth'); | |||
var height = foundImg.getAttribute('thumbheight'); | |||
var thumbURL = foundImg.getAttribute('thumburl'); | |||
var lastUser = foundImg.getAttribute('user'); | |||
var descURL = foundImg.getAttribute('descriptionurl'); | |||
// API returns link to local description page even for Commons images. | |||
// However, we want a direct link to Commons. | |||
if (isCommons) { | |||
descURL = descURL.replace(/en\.wikipedia\.org/, "commons.wikimedia.org"); | |||
descURL = descURL.replace(/\/\/secure\.wikimedia\.org\/wikipedia\/en/, "commons.wikimedia.org"); | |||
} | |||
// build the image info into the warning section of our page: | |||
thumbDiv = fuwGet('warningImageThumb'); | |||
if (thumbDiv) { | |||
// make all links point to description page: | |||
var thumbA = thumbDiv.getElementsByTagName('a'); | |||
for (i = 0; i<thumbA.length; i++) { | |||
thumbA[i].setAttribute('href', descURL); | |||
} | |||
// insert the image itself: | |||
var thumbImg = thumbDiv.getElementsByTagName('img'); | |||
if (thumbImg.length > 0) { | |||
thumbImg = thumbImg[0]; | |||
thumbImg.setAttribute('src', thumbURL); | |||
thumbImg.setAttribute('width', width); | |||
thumbImg.setAttribute('height', height); | |||
} | |||
// insert the name of the last uploader: | |||
var thumbSpan = fuwGet('existingImageUploader'); | |||
// TO DO: turn this into a proper link | |||
if (thumbSpan) thumbSpan.innerHTML = lastUser; | |||
} | |||
} | |||
warn = window.fuw.warn; | |||
warn.ImageOnCommons = exists && isCommons; | |||
warn.ImageExists = exists && !isCommons; | |||
fuwUpdateOptions(); | |||
} | |||
}); | |||
} | |||
// =========================================================== | |||
// onchange event handler for the local filename box | |||
// =========================================================== | |||
fuwValidateFile = function() { | |||
fuwCheckFileExtension(); | |||
fuwUpdateOptions(); | |||
} | |||
// =========================================================== | |||
// onchange event handler for the name input box | |||
// =========================================================== | |||
fuwValidateFilename = function() { | |||
fuwCleanFilename(); | |||
if ( | |||
fuwCheckLegalFilename() && | |||
fuwCheckPoorFilename() && | |||
fuwCheckFileExtension()) { | |||
// after fuwCheckFileExists(), | |||
// fuwUpdateOptions will be triggered | |||
// by the callback function after Ajax completion | |||
fuwCheckFileExists(); | |||
} | |||
else { | |||
// if there's been no Ajax call. | |||
fuwUpdateOptions(); | |||
} | |||
}; | |||
// ========================================================== | |||
// function fuwValidateNFArticle() | |||
// ========================================================== | |||
// This is the validation routine for the obligatory | |||
// article-to-be-used-in field for non-free files. It queries | |||
// api.php about the target article through an Ajax call. | |||
// It will store error info in the fuw.warn object, | |||
// triggering the following error on the next updateOptions(): | |||
// * warningNFArticleNotFound : target page doesn't exist. | |||
// * warningNFArticleNotMainspace : target is not an article. | |||
// * warningNFArticleDab : target is a disambiguation page. | |||
// Redirects will automatically be substituted. | |||
// ========================================================== | |||
fuwValidateNFArticle = function() { | |||
var nameBox = window.fuw.ScriptForm.NFArticle; | |||
oldname = name = nameBox.value; | |||
// cleanup article name: | |||
// automatically fix accidentally added [[ ... ]] and | |||
// regularize underscores | |||
name = $.trim(name); | |||
name = name.replace(/(^\[\[)|(\]\]$)/g, ""); | |||
// automatically fix article names entered as full urls: | |||
name = name.replace(/^https?:\/\/en\.wikipedia\.org\/wiki\//, ""); | |||
name = name.replace(/^https?:\/\/en\.wikipedia\.org\/w\/index\.php\?title=/, ""); | |||
name = name.replace(/_/g, " "); | |||
if (name != oldname) nameBox.value = name; | |||
// do nothing more if field was blank | |||
if (!name) return; | |||
// using the jQuery wrapper for the Ajax functionality: | |||
$.ajax({ | |||
url : mw.util.wikiScript( 'api' ), | |||
type : 'GET', | |||
dataType: 'xml', | |||
traditional : true, | |||
data: { | |||
format: 'xml', | |||
action: 'query', | |||
titles: name, | |||
prop : 'info|categories|links' | |||
}, | |||
success: function(resp) { | |||
// callback function, called when API query has succeeded: | |||
var errorType = 0; | |||
var pg = resp.getElementsByTagName('page')[0]; | |||
var title = pg.getAttribute('title'); | |||
var target = title; | |||
if (pg.getAttribute('missing') != null) { | |||
// no page found under this title. | |||
errorType = 1; | |||
} | |||
else { | |||
var userspace = false; | |||
var ns = pg.getAttribute('ns'); | |||
var rd = pg.getAttribute('redirect'); | |||
if (ns != 0) { | |||
// not a mainspace page! | |||
errorType = 2; | |||
// try to detect if the target might be a user space draft: | |||
if (title.match(new RegExp("User( talk)?:" + mw.config.get('wgUserName')))) { | |||
userspace = true; | |||
} | |||
} | |||
else if (rd != null) { | |||
// redirect page | |||
// API returns an empty redirect="" attribute if | |||
// the page is a redirect | |||
var targets = pg.getElementsByTagName('pl'); | |||
for (i=0; i<targets.length; i++) { | |||
var link = targets[i]; | |||
if (link.getAttribute('ns')==0) { | |||
target = link.getAttribute('title'); | |||
errorType = 3; | |||
break; | |||
} | |||
} | |||
} | |||
else { | |||
// check for disambiguation categories | |||
var cats = pg.getElementsByTagName('cl'); | |||
for (i=0; i<cats.length; i++) { | |||
var cat = cats[i]; | |||
if (cat.getAttribute('title') == "Category:All disambiguation pages") { | |||
errorType = 4; | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
warn = window.fuw.warn; | |||
warn.NFArticleNotFound = (errorType==1); | |||
warn.NFArticleNotMainspace = (errorType==2); | |||
warn.UserspaceDraft = ((errorType==2) && userspace); | |||
warn.NFArticleDab = (errorType==4); | |||
warn.NFArticleOK = (errorType==0); | |||
// fix links in error messages: | |||
if (warn.NFArticleNotFound) { | |||
fuwMakeWikilink(fuwGet('warningNFArticleNotFound').getElementsByTagName('A')[0], target, true); | |||
} | |||
else if (warn.NFArticleNotMainspace) { | |||
fuwMakeWikilink(fuwGet('warningNFArticleNotMainspace').getElementsByTagName('A')[0], target); | |||
} | |||
else if (warn.NFArticleDab) { | |||
fuwMakeWikilink(fuwGet('warningNFArticleDab').getElementsByTagName('A')[0], target); | |||
} | |||
else if (warn.NFArticleOK) { | |||
fuwMakeWikilink(fuwGet('NFArticleOK').getElementsByTagName('A')[0], target); | |||
} | |||
if (errorType==3) { | |||
// automatically replace title with redirect target | |||
window.fuw.ScriptForm.NFArticle.value = target; | |||
// need to recursively call validation again now | |||
//if (confirm(name + " is a redirect. Follow it to " + target + "?")) { | |||
fuwValidateNFArticle(); | |||
//} | |||
} | |||
else { | |||
fuwUpdateOptions(); | |||
} | |||
} | |||
}); | |||
}; | |||
// ================================================ | |||
// manually reload script (just for testing) | |||
// ================================================ | |||
function fuwReload() { | |||
mw.loader.load( 'http://localhost/script/uploadscript.js' ); | |||
fuwReset(); | |||
} | |||
// ================================================ | |||
// reset forms | |||
// TO DO: add a button that actually triggers this. | |||
// ================================================ | |||
function fuwReset() { | |||
var forms = mw.util.$content[0].getElementsByTagName('form'); | |||
for (i = 0; i < forms.length; i++) { | |||
forms[i].reset(); | |||
window.fuw.warn = { }; | |||
window.fuw.opts = { }; | |||
} | |||
fuwSetVisible('UploadScriptArea', true); | |||
fuwSetVisible('fuwSuccess', false); | |||
fuwSetVisible('fuwWaiting', false); | |||
fuwUpdateOptions(); | |||
} | |||
// =============================================== | |||
// convenience functions for string handling | |||
// =============================================== | |||
function fuwAppendLines(parts) { | |||
// assemble a string from an array of strings. | |||
// treat every second element as a conditional | |||
// separator that will be included only if | |||
// surrounding elements are non-empty. | |||
var build = ""; | |||
for (var i = 0; i < parts.length; i += 2) { | |||
if (parts[i]) { | |||
if (build) build += parts[i - 1]; | |||
build += parts[i]; | |||
} | |||
} | |||
return build; | |||
} | |||
function fuwSurroundString(prefix, content, suffix) { | |||
// put a prefix and a suffix on a string, | |||
// if the input string is non-empty. | |||
if (content) | |||
return (prefix ? prefix : "") + content + (suffix ? suffix : ""); | |||
else return ""; | |||
} | |||
// ======================================================== | |||
// convenience function for accessing the contents of the | |||
// dummy TargetIFrame | |||
// ======================================================== | |||
function fuwGetDocumentFromIFrame(iframe) { | |||
var doc = (iframe.contentDocument ? iframe.contentDocument : iframe.contentWindow.document); | |||
if (doc.XMLDocument) { | |||
doc = doc.XMLDocument; | |||
} | |||
return doc; | |||
} | |||
// ======================================================== | |||
// event handler for the dummy TargetIFrame's onload event. | |||
// TO DO: expand stub to add real notification of success, | |||
// link to new file page, instructions about how to include | |||
// file in articles, etc. | |||
// ======================================================== | |||
function fuwUploadCompleted() { | |||
var doc = fuwGetDocumentFromIFrame(fuwGet('TargetIFrame')); | |||
if (doc) { | |||
//alert(doc); | |||
fuwSetVisible('successThumb', false); | |||
var fuw = window.fuw; | |||
var name = fuw.opts.InputName; | |||
var uploads = doc.getElementsByTagName('upload'); | |||
var success = false; | |||
for (i = uploads.length-1; i>=0; i--) { | |||
if (uploads[i].getAttribute('result') == 'Success') { | |||
success = true; | |||
// need to get the real resulting filename here; might be different from the requested one in some cases. | |||
name = uploads[i].getAttribute('filename'); | |||
break; | |||
} | |||
} | |||
if (success) { | |||
// need another ajax call to check the file is actually there, | |||
// and to retrieve its direct thumb img url: | |||
$.ajax({ | |||
url : mw.util.wikiScript( 'api' ), | |||
type : 'GET', | |||
dataType: 'xml', | |||
traditional : true, | |||
data: { | |||
format: 'xml', | |||
action: 'query', | |||
titles: 'File:' + name, | |||
prop : 'imageinfo', | |||
iiprop: 'url', | |||
iiurlwidth: 120 | |||
}, | |||
success: function(resp) { | |||
// callback function, called when API query has succeeded: | |||
// see if the request has returned info from an existing image: | |||
var foundImg = resp.getElementsByTagName('ii')[0]; | |||
if (foundImg) { | |||
// need this data for creating our own image thumb link | |||
var width = foundImg.getAttribute('thumbwidth'); | |||
var height = foundImg.getAttribute('thumbheight'); | |||
var thumbURL = foundImg.getAttribute('thumburl'); | |||
var lastUser = foundImg.getAttribute('user'); | |||
var descURL = foundImg.getAttribute('descriptionurl'); | |||
// build the thumbnail in the success message: | |||
thumbDiv = fuwGet('successThumb'); | |||
// make link point to description page: | |||
var thumbA = thumbDiv.getElementsByTagName('a')[0]; | |||
thumbA.href = descURL; | |||
// insert the image itself: | |||
var thumbImg = thumbDiv.getElementsByTagName('img')[0]; | |||
thumbImg.setAttribute('src', thumbURL); | |||
thumbImg.setAttribute('width', width); | |||
thumbImg.setAttribute('height', height); | |||
fuwSetVisible(thumbDiv, true); | |||
} | |||
} | |||
}); | |||
fuwMakeWikilink( | |||
fuwGet('fuwSuccessLink2').getElementsByTagName('a')[0], | |||
'File:' + name); | |||
fuwGet('placeholderExFilename1').innerHTML = name; | |||
fuwGet('placeholderExFilename2').innerHTML = name; | |||
fuwSetVisible('fuwSuccess', true); | |||
fuwSetVisible('fuwWaiting', false); | |||
} | |||
else { | |||
var err = doc.getElementsByTagName('error'); | |||
if (err) { | |||
var info = err[0].getAttribute('info'); | |||
var details = err[0].getElementsByTagName('detail'); | |||
var add = ""; | |||
for (i = 0; i < details.length; i++) { | |||
if (add.length > 0) add += ", "; | |||
add += details[i].textContent; | |||
} | |||
if (add) { | |||
info = info + " (" + add + ")"; | |||
} | |||
alert("Upload failed: " + info); | |||
} | |||
else { | |||
alert("Unknown error: upload may have failed."); | |||
} | |||
} | |||
} | |||
} | |||
// ======================================================== | |||
// clean out dummy IFrame before submitting a request | |||
// ======================================================== | |||
function fuwResetTargetIFrame() { | |||
var doc = fuwGetDocumentFromIFrame(fuwGet('TargetIFrame')); | |||
if (doc) { | |||
while (doc.hasChildNodes()) { | |||
doc.removeChild(doc.firstChild); | |||
} | |||
} | |||
} | |||
// ======================================================== | |||
// Event handler for the real submit button | |||
// ======================================================== | |||
function fuwSubmitUpload() { | |||
var fuw = window.fuw; | |||
var frm = fuw.TargetForm; | |||
fuw.collectInput(); | |||
fuw.formatOutput(false); | |||
// we will use the iframe's onload event to trigger a function that | |||
// adds success notification etc. | |||
fuwResetTargetIFrame(); | |||
var ifr = fuwGet('TargetIFrame'); | |||
if (ifr.attachEvent) { | |||
// workaround for IE, according to | |||
// http://www.nczonline.net/blog/2009/09/15/iframes-onload-and-documentdomain/ | |||
ifr.attachEvent("onload", fuwUploadCompleted); | |||
} | |||
else { | |||
// all other browsers | |||
ifr.onload = fuwUploadCompleted; | |||
} | |||
if (fuwTesting) { | |||
fuwSetVisible('placeholderTestForm', false); | |||
} | |||
fuwSetVisible('UploadScriptArea', false); | |||
fuwMakeWikilink( | |||
fuwGet('fuwSuccessLink').getElementsByTagName('a')[0], 'File:' + fuw.opts.InputName); | |||
fuwSetVisible('fuwWaiting', true); | |||
frm.submit(); | |||
var opts = window.fuw.opts; | |||
// the API won't overwrite the description page text while overwriting | |||
// a file, which is really, really, really annoying and stupid. | |||
// So in the opts.OverwriteDifferent scenario, we need to edit | |||
// the description page through a separate ajax call. Dang. | |||
if (opts.OverwriteDifferent) { | |||
$.ajax({ | |||
url : mw.util.wikiScript('api'), | |||
type : 'POST', | |||
dataType : 'xml', | |||
data : { | |||
format : 'xml', | |||
action : 'edit', | |||
title : 'File:' + opts.InputName, | |||
token : mw.user.tokens.get('csrfToken'), | |||
summary : opts.EditSummary, | |||
text : ($('#TargetForm .[name="text"]')[0]).value | |||
} | |||
}); | |||
} | |||
} | |||
// ======================================================= | |||
// Event handler for the Commons submit button | |||
// ======================================================= | |||
function fuwSubmitCommons() { | |||
var fuw = window.fuw; | |||
fuw.collectInput(); | |||
var url = fuw.formatOutput(true); | |||
alert("You will now be redirected to Commons. \nPlease use the Commons upload form to add categories to your file description, and then complete the upload."); | |||
window.location = url; | |||
} | |||
// ======================================================= | |||
// Event handler for the test submit button | |||
// (write description string to sandbox only) | |||
// ======================================================= | |||
function fuwSubmitSandbox() { | |||
var frm = window.fuw.TestForm; | |||
$.ajax({ | |||
url : mw.util.wikiScript( 'api' ), | |||
type : 'POST', | |||
dataType: 'xml', | |||
data: { | |||
format: 'xml', | |||
action: 'edit', | |||
title : mw.config.get('wgPageName') + "/sandbox", | |||
token : mw.user.tokens.get('csrfToken'), | |||
recreate : 1, | |||
summary : frm.SandboxSummary.value, | |||
text : frm.SandboxText.value | |||
}, | |||
success: function(resp) { | |||
alert("Sandbox page edited!"); | |||
} | |||
}); | |||
} | |||
// ======================================================== | |||
// convenience wrapper function to replace calls to | |||
// document.getElementById() | |||
// to avoid browser incompatibility | |||
// ======================================================== | |||
function fuwGet(target) { | |||
if (!!target && !!target.nodeType) return target; | |||
else { | |||
var found = $('#' + target); | |||
if (found) return found[0]; | |||
} | |||
return undefined; | |||
} | |||
// ======================================================== | |||
// onload hook function, loading this script | |||
// ======================================================== | |||
$(function() { | |||
if (fuwGet('UploadScriptArea')) { | |||
window.fuw = new fuwGlobal(); | |||
fuwUpdateOptions(); | |||
} | |||
}); | |||
// </nowiki> |