/* ______________________________________________________________________________________ * | | * | === WARNING: GADGET FILE === | * | Changes to this page affect many users. | * | Please discuss changes on the talk page or on [[MediaWiki_talk:Gadgets-definition]] | * | before editing. | * |_____________________________________________________________________________________| * * "Forms" feature, to be used by the Wikimedia Foundation's Grants Programme */ // var formsGadget = { 'createDialog' : function(){ var that = this; var dialogDict = { dialogClass: 'formsGadget', autoOpen: false, //title: that.formDict.config['dialog-title'], width: '495px', modal: true, closeOnEscape: true, resizable: false, draggable: false, }; var dialog = $('#formsDialogExpand'); if(dialog.length){ this.dialog = dialog.dialog(dialogDict); } else{ this.dialog = $('
').dialog(dialogDict); } dialog.append('
'); }, 'dialog' : null, 'openPanel': function(){ this.dialog.dialog('open'); }, 'openDialog' : function () { if (this.dialog === null){ this.createDialog(); } else{ this.dialog.dialog('open'); } }, 'cleanupDialog': function (){ if (this.dialog){ this.dialog.dialog('destroy'); } this.dialog = null; $('#formsDialogExpand').text(''); }, 'utilities' : { /* * Path to the gadget config file */ 'configPath' : 'Wikipedia:FormWizard/Config/', 'apiUrl' : 'https://en.wikipedia.org/w/api.php?callback=?', 'gadgetNamespace' : function(){ var grant = mw.config.get('wgTitle').split('/')[0].replace(/ /g,'_'); return grant; }, /* * To detect the users default language */ 'userLanguage' : function(){ return mw.config.get('wgUserLanguage'); }, /* * To detect the language of the page */ 'contentLanguage' : function(){ return mw.config.get('wgContentLanguage'); }, /* * Removes leading/trailing spaces & user signature * ( It is added through the code) */ 'cleanupText' : function(text){ text = $.trim(text)+' '; var indexOf = text.indexOf('~~~~'); if ( indexOf == -1 ){ return text; } else{ return text.slice(0,indexOf)+text.slice(indexOf+4); } }, /* * The config files which can be translated with the help of the * translation tool generates the dict with the values having a * lot of space in the key value pairs. This function strips the * whitespace. */ 'stripWhiteSpace' : function(dict){ for (key in dict){ dict[key] = typeof(dict[key]) == 'object' ? this.stripWhiteSpace(dict[key]) : $.trim(dict[key]); } return dict; }, }, 'formElement' : { /* * Elements being supported * Small textbox * Large textbox * Checkbox list * Radio button list * Stepper list * Image/s * Dropdown * Link * Text */ 'hiddenInfoboxFields' : [], 'found' : false, 'timestamp' : 0, 'defaultTextBoxConfig': { 'type': 'smallTextBox', 'placeholder': 'Enter the text', 'title': 'Textbox', 'characterLength':100, 'mandatory':false, 'error-messageLength': 'Max length reached', 'error-notFilled': 'Mandatory field', 'value': '', 'parent': '', 'id': null, 'comment': '' }, 'elementContainer' : function(){ var div = document.createElement('div'); div.className = 'elementContainer'; return div; }, 'addDescription': function(dict,div){ for (key in dict){ if(key.indexOf('text') != -1){ this.addText(div,dict[key],'text'); delete dict[key]; } } return div; }, 'checkTitle' : function(string,exists,titleStem,type){ var that = this; var apiUrl = formsGadget.utilities.apiUrl; var title = titleStem + string; var searchDict = { 'action':'query', 'format':'json', 'titles':title, 'prop':'imageinfo' }; var timestamp = Date.now(); console.log('String before ajax', string); return $.getJSON(apiUrl,searchDict,function(data){ var query = data['query']; var pages = data['query']['pages']; var pageId = Object.keys(pages); var pageExists = pageId != -1 ? true : false; var imageExists = pages[pageId]['imagerepository'] ? true : false; var value = 0; if (type == 'image'){ value = imageExists; } else{ value = pageExists; } if(that.timestamp < timestamp){ that.timestamp = timestamp; that.found = !(value ^ exists) ; //temp console.log('String ',string, 'found ',that.found); } }); }, 'inputList': function(type,list,title,dict,role){ var div = this.elementContainer(); div = this.addText(div,title,'title'); this.addDescription(dict,div); for (elem in list){ var label = document.createElement('div'); var input = document.createElement('input'); var key = list[elem]['key']; var value = list[elem]['value']; input.type = type; if (type == 'number'){ input.min = dict['min']; input.max = dict['max']; } input.value = value; input.setAttribute('data-add-to',dict['add-to']); if(role){ input.setAttribute('data-role',true); } input.className = 'inputListItem'; input.setAttribute('data-add-to-attribute',key); var descriptionText = key.replace(/_/g,' '); descriptionText = descriptionText.slice(0,1).toUpperCase() + descriptionText.slice(1); var description = document.createElement('span'); description.className = 'inputListItemDescription'; description.textContent = descriptionText; label.appendChild(input); label.appendChild(description); div.appendChild(label); } return div; }, 'createTextBoxConfig':function(defaultConfig,actualConfig){ var config = {}; for (key in defaultConfig){ actualConfig[key] = key in actualConfig? actualConfig[key] : defaultConfig[key]; if (key == 'mandatory' && (typeof(actualConfig[key]) == 'string')){ if (actualConfig[key] == 'true'){ actualConfig[key] = true; } else{ actualConfig[key] = false; } } } return actualConfig; }, 'textBox': function(dict,type,callback,element){ var config = this.createTextBoxConfig(this.defaultTextBoxConfig,dict); var className = type == 'small'? 'smallTextBox': 'largeTextBox'; var div = this.elementContainer(); div = this.addText(div,config['title'],'title'); this.addDescription(dict,div); if (type == 'large'){ var input = document.createElement('textarea'); } else{ var input = document.createElement('input'); } //cleanup if(dict['visibility'] == 'hidden'){ div.style['display'] = 'none'; input.value = dict['value']; } //Cleanup if('page-title' in dict){ input.setAttribute('page-title',true); } if (dict['id']){ input.id = dict['id']; } input.setAttribute('type','text'); input.setAttribute('class',className); input.setAttribute('placeholder',config['placeholder']); input.setAttribute('maxlength',config['characterLength']); input.setAttribute('data-mandatory',config['mandatory']); input.setAttribute('data-comment',config['comment']); input.setAttribute('data-add-to',config['add-to']); var conditionalAttr = config['add-to'] == 'infobox' ? config['infobox-param'] : config['section-header']; input.setAttribute('data-add-to-attribute',conditionalAttr); var that = this; /* Word limit */ $(input).on('change keyup paste',function(){ /* Checking if link/file/page exists */ var inputTextBox = this; var enteredString = $(this).val(); if(!enteredString && !dict['mandatory']){ $('#formsDialogExpand [elemType="button"]').trigger('enableButtons'); $(inputTextBox).parent().removeClass('entrySatisfying entryNotSatisfying'); that.timestamp = Date.now(); that.found = true; } else{ if( 'validate' in dict && enteredString){ var exists = dict['validate'] == 'exists' ? 1:0; var titleStem = 'image' in dict ? '' : that.formDict.config['page-home']; $.when(that.checkTitle(enteredString,exists,titleStem,dict['type'])).then(function(){ //Cleanup & remove redundant code $(inputTextBox).removeClass('entrySatisfying entryNotSatisfying'); $(inputTextBox).addClass(that.found ? 'entrySatisfying' : 'entryNotSatisfying'); $(inputTextBox).parent().removeClass('entrySatisfying entryNotSatisfying'); $(inputTextBox).parent().addClass(that.found ? 'entrySatisfying' : 'entryNotSatisfying'); if (that.found){ $('#formsDialogExpand [elemType="button"]').trigger('enableButtons'); if(typeof(callback) === 'function' && that.found){ //Api url var apiUrl = formsGadget.utilities.apiUrl; $.getJSON(apiUrl,{'action':'parse', 'format':'json', 'text':'[['+enteredString+']]' },function(data){ console.log(data['parse']['text']['*']); var src = $('
').html(data['parse']['text']['*']).find('img').attr('src'); if(src){ callback(element, src); } }); } } else{ $('#formsDialogExpand [elemType="button"]').trigger('disableButtons'); } }); } } }); //To show validation inputElementWrapper = document.createElement('span'); $(inputElementWrapper).addClass('inputElementWrapper'); if('validate' in dict){ $(inputElementWrapper).addClass('validationContainer'); } if(dict['mandatory']){ $(inputElementWrapper).addClass('mandatoryContainer'); } inputElementWrapper.appendChild(input); div.appendChild(inputElementWrapper); return div; }, 'smallTextBox': function (dict,callback,element) { return this.textBox(dict,'small',callback,element); }, 'largeTextBox': function (dict,callback,element) { return this.textBox(dict,'large',callback,element); }, 'checkboxList': function (dict) { var list = dict['choiceList']; var hidden = dict['hidden']; if('hidden' in dict){ this.hiddenInfoboxFields = this.hiddenInfoboxFields.concat(dict['hidden']); } return this.inputList('checkbox',list,dict['title'],dict); }, 'addText': function(container,text,type){ var textHolder = $('

'); textHolder.text(text); if (type == 'title'){ textHolder.addClass('title'); } else if (type == 'text'){ textHolder.addClass('text'); } else{ textHolder.addClass(type); } container.appendChild(textHolder[0]); return container; }, 'text': function(dict){ var textHolder = $('

'); return textHolder.text(dict['string'])[0]; }, 'stepperList': function (dict) { var list = dict['choiceList']; if('hidden' in dict){ this.hiddenInfoboxFields = this.hiddenInfoboxFields.concat(dict['hidden']); } dict['min'] = 0; if(!('max' in dict)){ dict['max'] = 9; } return this.inputList('number',list,dict['title'],dict,true); }, 'dropdownList': function(dict){ var div = this.elementContainer(); div = this.addText(div,dict['title'],'title'); this.addDescription(dict,div); var values = dict['values']; var select = document.createElement('select'); select.setAttribute('class','dropdown'); select.setAttribute('data-placeholder',dict['placeholder']); select.setAttribute('data-add-to',dict['add-to']); select.setAttribute('data-add-to-attribute',dict['infobox-param']); var option; for (elem in values){ option = $('