User:William Avery/test.js

class taxoboxalyzer { constructor { this.dataapi = new mw.ForeignApi('https://www.wikidata.org/w/api.php'); this.wikidatanavkey = '' this.taxoboxalyzerButton = false this.markupPromise = false //       // This gadget is only wanted on wiki pages with taxoboxes //       if (mw.config.get('wgPageContentModel') != 'wikitext') return this.taxobox = $('table[class=\'infobox biota\']'); if (!this.taxobox.length) return //       var trow = $(' ') $('tbody', this.taxobox).prepend(trow) var uibox = $(' ').attr('id', 'taxoboxalyzer').css({           position: 'absolute',            top: '-66px',            left: '-1px',            'background-color': '#dcf9ec',            'z-index': 9999        }).append($(' ').text('Taxoboxalyzer').css({ 'background-color': '#9FE2BF' }).append($(' ').attr('id', 'tbx-xpand').text('+').on('click', (e) => {           if ($(e.target).text == '+') {                $(e.target).html('&minus;')                $('#tbx-uibody').parent.show            } else {                $(e.target).text('+')                $('#tbx-uibody').parent.hide            }        }).css({            'background-color': '#AAFF00',            float: 'right',            'font-weight': '900',            'padding-left': '3px',            'padding-right': '3px'        })), $(' ').append($(' ').attr('id', 'tbx-uibody')).hide).appendTo(trow) $('#taxoboxalyzer').draggable({           handle: $('#tbx-xpand').parent        }).css({            'border-color': 'darkgreen',            'border-style': 'outset',            'border-width': 'thin'        }) //       // Make a current date string for Wikidata operations //       var datetoday = new Date; datetoday.setUTCHours(0, 0, 0, 0) this.datetoday = datetoday.toISOString.replace('.000Z', 'Z')

// Input for English description $('#tbx-uibody').append(taxoboxalyzer.makeRow('taxoboxalyzer-wd-desc'))

$('#taxoboxalyzer-wd-desc').append(taxoboxalyzer.makeText('taxoboxalyzer-wd-desc-text', 'Description'))

$('#taxoboxalyzer-wd-desc').on('change', (e) => {           if (!('en' in this.entity.descriptions))                this.entity.descriptions['en'] = {                    "language": "en",                    "value": ""                }            this.entity.descriptions.en.value = $('#taxoboxalyzer-wd-desc-text').val        })

// Dropdown for Wikidata instance-of property $('#tbx-uibody').append(taxoboxalyzer.makeRow('taxoboxalyzer-wd-inst'))

$('#taxoboxalyzer-wd-inst').append(taxoboxalyzer.makeSelect('taxoboxalyzer-wd-inst-select', 'Instance of')) $('#taxoboxalyzer-wd-inst-select').append(taxoboxalyzer.makeOption('Q16521', 'taxon')) .append(taxoboxalyzer.makeOption('Q23038290', 'fossil taxon')) .append(taxoboxalyzer.makeOption('Q310890', 'monotypic taxon')) .append(taxoboxalyzer.makeOption('Q98961713', 'extinct taxon')) .append(taxoboxalyzer.makeOption('Q2568288', 'ichnotaxon')) .append(taxoboxalyzer.makeOption('Q47487597', 'monotypic fossil taxon')) .append(taxoboxalyzer.makeOption('Q42621', 'hybrid')) .append(taxoboxalyzer.makeOption('Q235536', 'incertae sedis')) .append(taxoboxalyzer.makeOption('Q713623', 'clade')) .append(taxoboxalyzer.makeOption('Q848328', 'serotype')) .append(taxoboxalyzer.makeOption('Q857968', 'candidatus')) .append(taxoboxalyzer.makeOption('Q17487588', 'unavailable combination')) $('#taxoboxalyzer-wd-inst').on('change', (e) => {           this.setClaimItem('P31', e.target.value)        })

// Dropdown for Wikidata rank property $('#tbx-uibody').append(taxoboxalyzer.makeRow('taxoboxalyzer-wd-rank'))

$('#taxoboxalyzer-wd-rank').append(taxoboxalyzer.makeSelect('taxoboxalyzer-wd-rank-select', 'Rank')) $('#taxoboxalyzer-wd-rank-select').append(taxoboxalyzer.makeOption('Q34740', 'genus')) .append(taxoboxalyzer.makeOption('Q7432', 'species')) .append(taxoboxalyzer.makeOption('Q3965313', 'subtribe')) .append(taxoboxalyzer.makeOption('Q227936', 'tribe')) .append(taxoboxalyzer.makeOption('Q164280', 'subfamily')) .append(taxoboxalyzer.makeOption('Q35409', 'family')) $('#taxoboxalyzer-wd-rank').on('change', (e) => {           this.setClaimItem('P105', e.target.value)        })

// Input for Wikidata taxon name property $('#tbx-uibody').parent.append(taxoboxalyzer.makeRow('taxoboxalyzer-wd-name'))

$('#taxoboxalyzer-wd-name').append(taxoboxalyzer.makeText('taxoboxalyzer-wd-name-text', 'Name'))

$('#taxoboxalyzer-wd-name').on('change', (e) => {           this.setClaimString('P225', e.target.value)        })

// Input for Wikidata first description ref $('#tbx-uibody').parent.append(taxoboxalyzer.makeRow('taxoboxalyzer-wd-descref')) $('#taxoboxalyzer-wd-descref').append(taxoboxalyzer.makeText('taxoboxalyzer-wd-descref', '1st desc'))

$('#taxoboxalyzer-wd-descref').on('change', (e) => {           var descind = -1            var enind = -1            if (!('references' in this.entity.claims['P225'][0]))                this.entity.claims['P225'][0]['references'] = []            for (const ref of this.entity.claims['P225'][0]['references']) {                if ('P143' in ref.snaks)                    enind = this.entity.claims['P225'][0]['references'].indexOf(ref)                if ('P248' in ref.snaks)                    descind = this.entity.claims['P225'][0]['references'].indexOf(ref)            }

if (descind < 0) descind = this.entity.claims['P225'][0]['references'].length this.entity.claims['P225'][0]['references'][descind] = { "snaks": { "P248": [{ "snaktype": "value", "property": "P248", "datavalue": { "type": "wikibase-entityid", "value": { "id": e.target.value }                       }                    }],                    "P6184": [{ "snaktype": "value", "property": "P6184", "datavalue": { "type": "wikibase-entityid", "value": { "id": "Q1361864" }                       }                    }]                },                "snaks-order": ["P248", "P6184"] }           if (enind > -1) this.entity.claims['P225'][0]['references'].splice(enind, 1) })

// Input for Wikidata taxon author citation property $('#tbx-uibody').parent.append(taxoboxalyzer.makeRow('taxoboxalyzer-wd-cite'))

$('#taxoboxalyzer-wd-cite').append(taxoboxalyzer.makeText('taxoboxalyzer-wd-cite-text', 'Auth.cite'))

$('#taxoboxalyzer-wd-cite').on('change', (e) => {           this.setClaimString('P6507', e.target.value)        })

// Input for Wikidata parent taxon property $('#tbx-uibody').append(taxoboxalyzer.makeRow('taxoboxalyzer-wd-parent'))

$('#taxoboxalyzer-wd-parent').append(taxoboxalyzer.makeText('taxoboxalyzer-wd-parent-text', 'Parent')) $('#taxoboxalyzer-wd-parent-text').attr('title', 'Enter a QID. Clicking on a label in the taxobox will attempt to retrieve the relevant value. Lack of a link or presence of a redirect will frustrate this action.') $('#taxoboxalyzer-wd-parent').on('change', (e) => {           this.setClaimItem('P171', e.target.value)        }) this.taxoboxalyzerButton = $(" ").html('Update Wikidata').button taxoboxalyzer.makeRow('taxoboxalyzer-button-row').append(this.taxoboxalyzerButton) $('#tbx-uibody').append(this.taxoboxalyzerButton)

this.taxoboxalyzerSearchButton = $(" ").html('Search Wikidata').button taxoboxalyzer.makeRow('taxoboxalyzer-searchbutton-row').append(this.taxoboxalyzerSearchButton) $('#tbx-uibody').append(this.taxoboxalyzerSearchButton)

// Apply CSS after creating all ui buttons $('#taxoboxalyzer .ui-button, #taxoboxalyzer .ui-button .ui-button-text') .css({               'font-size': '.8em',                'line-height': '1em'            }) $('#taxoboxalyzer .ui-button, #taxoboxalyzer .ui-button .ui-button-text') .css('padding', '.3em .3em') $('#taxoboxalyzer').tooltip this.markupPromise = this.getMarkup this.preferred_binomial = this.tQuery('.binomial i'); let wikibseurl = $("#t-wikibase a").attr('href'); if (wikibseurl) { let wikibsearr = wikibseurl.split('/'); this.wikidatanavkey = wikibsearr[wikibsearr.length - 1]; this.entityPromise = this.getEntity(this.wikidatanavkey) this.entityPromise.then((ent) => {               this.entity = ent;                console.log(JSON.stringify(ent))                if ('en' in this.entity.descriptions)                    $('#taxoboxalyzer-wd-desc-text').val(this.entity.descriptions.en.value)

if ('P31' in this.entity.claims) $('#taxoboxalyzer-wd-inst-select').val(this.entity.claims.P31[0].mainsnak.datavalue.value.id) else this.setClaimItem('P31', 'Q16521') if (!('P105' in this.entity.claims)) { this.setClaimItem('P105', 'Q34740') if (this.preferred_binomial) this.setClaimItem('P105', 'Q7432') if (this.isHierBold('Genus')) this.setClaimItem('P105', 'Q34740') }               $('#taxoboxalyzer-wd-rank-select').val(this.entity.claims.P105[0].mainsnak.datavalue.value.id)

if (!('P225' in this.entity.claims)) { if (this.preferred_binomial) this.setClaimString('P225', this.preferred_binomial) if (this.isHierBold('Genus')) this.setClaimString('P225', this.getHierField('Genus')) }               if ('P225' in this.entity.claims) $('#taxoboxalyzer-wd-name-text').val(this.entity.claims.P225[0].mainsnak.datavalue.value)

if ('P6507' in this.entity.claims) $('#taxoboxalyzer-wd-cite-text').val(this.entity.claims.P6507[0].mainsnak.datavalue.value) if ('P171' in this.entity.claims) $('#taxoboxalyzer-wd-parent-text').val(this.entity.claims.P171[0].mainsnak.datavalue.value.id) })       }

this.markupPromise.then( => {           if (!(this.markup.match(/{{[Tt]axon?\s*bar\b/)) || this.markup.match(/{{\s*[Tt]axon?\s*bar\s*(\|from=)?\s*}}/))                $('#tbx-uibody').parent.append(taxoboxalyzer.makeRow('taxoboxalyzer-add-tbar-row').append($(' ').attr('id', 'taxoboxalyzer-add-tb').text('taxobar:' + this.wikidatanavkey)))            $('#taxoboxalyzer-add-tb').on('click',  => { this.addTaxonbar(this.wikidatanavkey) })       })        this.taxoboxalyzerButton.on('click',  => {            this.editEntity(this.entity, ' from enwiki', this.wikidatanavkey)        }) this.taxoboxalyzerSearchButton.on('click', => {            this.doSearch        }) // Click on a label to set the taxon as wd parent $('tbody tr td:has(a)', this.taxobox).prev.on('click', (e) => {           let href = $(e.target).closest('td').next.find('a').attr('href')            if (!href) return;            let parent = href.replace('/wiki/', '')            console.log(parent)            this.getPageProps(parent).then((pageprops) => { $('#taxoboxalyzer-wd-parent-text').val(pageprops.wikibase_item) this.setClaimItem('P171', pageprops.wikibase_item) })       })    }    static makeOption(val, text) { return $(' ').attr('value', val).text(text) }   static makeRow(id) { return $(' ').append($(' ').attr('id', id)) }   static makeText(id, labelText) { return $(' ').css({           display: 'flex',            'flex-direction': 'row'        }) .append($(' ').attr('for', id).text(labelText)) .append($(' ').attr('type', 'text').attr('id', id)) }   static makeSelect(id, labelText) { return $(' ').css({           display: 'flex',            'flex-direction': 'row'        }) .append($(' ').attr('for', id).text(labelText)) .append($(' ').attr('id', id)) }   tQuery(selector) { return $(selector, this.taxobox).text; }   tQueryRaw(selector) { return $(selector, this.taxobox); }   getHierField(level) { var fldVal = this.tQuery('tr td:contains(\'' + level + ':\') + td b'); if (!fldVal) fldVal = this.tQuery('tr td:contains(\'' + level + ':\') + td i'); if (!fldVal) fldVal = this.tQuery('tr td:contains(\'' + level + ':\') + td'); return fldVal.split(/[\n\[]/)[0]; }   isHierBold(level) { var btext = this.tQuery('tr td:contains(\'' + level + ':\') + td b'); if (!btext.length) btext = this.tQuery('tr td:contains(\'' + level + ':\') + td a.selflink'); return (btext.length > 0); }   getMarkup { var thisProm = new Promise((accept, reject) => {           var api = new mw.Api;            api.get({ action: 'query', prop: 'categories|revisions', format: 'json', cllimit: '50', cldir: 'ascending', rvprop: 'ids|timestamp|content', rvdir: 'older', pageids: mw.config.get('wgArticleId') }).done((data) => { this.rev = data.query.pages[mw.config.get('wgArticleId')].revisions[0]; this.permalink = 'https://en.wikipedia.org/w/index.php?title=' + mw.config.get('wgPageName').replace(' ', '_') + '&oldid=' + this.rev.revid this.cats = data.query.pages[mw.config.get('wgArticleId')].categories; this.markup = this.rev['*']; accept; })       });        return thisProm; }   getPageProps(title) { var thisProm = new Promise((accept, reject) => {           var api = new mw.Api;            api.get({ action: 'query', prop: 'pageprops', format: 'json', titles: title }).done((data) => { accept(data.query.pages[Object.keys(data.query.pages)[0]].pageprops); })       });        return thisProm; }   editEntity(data, summary, id) { console.log("Edit entity"); var thisProm = new Promise((accept, reject) => {           var dataObj = {                action: 'wbeditentity',                data: JSON.stringify(data),                summary: summary            }            if (id)                dataObj['id'] = id            else                dataObj['new'] = 'item'            this.dataapi.postWithToken('csrf', dataObj)                .fail((obj) => { var dialogConts = $(' The API returned the code "' + obj + '" ') console.log(dialogConts.text) $(' ').append(dialogConts).dialog({                       modal: true,                        width: 500                    }) reject(Error("Get entity: " + obj)); })               .done((obj) => { if (obj.success && obj.success == 1) { this.entity = obj.entity }                   console.log("Wikidata SUCCESS"); accept; });       });        return thisProm; }   getEntity(qnum) { var thisProm = new Promise((accept, reject) => {           this.dataapi.get({ action: 'wbgetentities', ids: qnum }).done((obj) => { if (obj.error) { reject(JSON.stringify(obj.error)); } else if (obj.entities && obj.entities[this.wikidatanavkey]) accept(obj.entities[this.wikidatanavkey]); else reject(Error(JSON.stringify(obj))) });       });        return thisProm; }   doSearch { console.log("TAXONBAR"); var thisProm = new Promise((accept, reject) => {           var searchTerm = $('#taxoboxalyzer-wd-name-text').val            this.dataapi.get({ action: 'wbsearchentities', format: 'json', search: searchTerm, language: 'en' }).done((obj) => { if (obj.error) { reject(obj.error); } else { var dialogConts if ('search' in obj) { dialogConts = $(' ').append($(' ').append($(' ').text('Key'))                           .append($(' ').text('Label'))                            .append($(' ').text('Description'))) for (const result of obj.search) { dialogConts.append($(' ').append($(' ').text(result.id))                               .append($(' ').text(result.label))                                .append($(' ').text(result.description))) }                   } else { dialogConts = $(' ').text('No matches found') }

$(' ').append(dialogConts).dialog({                       modal: true,                        width: 500                    }) accept('search' in obj ? obj.search : {}); }           });        });        return thisProm; }   enwikirefs { return [{ "snaks": { "P143": [{ "snaktype": "value", "property": "P143", "datavalue": { "type": "wikibase-entityid", "value": { "id": "Q328" }                   }                }],                "P4656": [{ "snaktype": "value", "property": "P4656", "datavalue": { "value": this.permalink, "type": "string" },                   "datatype": "url" }]           },            "snaks-order": ["P143", "P813"] }]   }    setClaimString(pval, strval) { if (!(pval in this.entity.claims)) { this.entity.claims[pval] = [{ "mainsnak": { "snaktype": "value", "property": pval, "datavalue": { "value": strval, "type": "string" },                   "datatype": "string" },               "type": "statement", "rank": "normal" }]       } else { this.entity.claims[pval][0].mainsnak.datavalue.value = strval }       this.entity.claims[pval][0]['references'] = this.enwikirefs console.log(JSON.stringify(this.entity))

}   setClaimItem(pval, qval) { if (!(pval in this.entity.claims)) { this.entity.claims[pval] = [{ "mainsnak": { "snaktype": "value", "property": pval, "datavalue": { "value": { "entity-type": "item", "numeric-id": parseInt(qval.replace('Q', '')), "id": qval },                       "type": "wikibase-entityid" },                   "datatype": "wikibase-item" },               "type": "statement", "rank": "normal" }]       } else { this.entity.claims[pval][0].mainsnak.datavalue.value.id = qval this.entity.claims[pval][0].mainsnak.datavalue.value['numeric-id'] = parseInt(qval.replace('Q', '')) }       this.entity.claims[pval][0]['references'] = this.enwikirefs console.log(JSON.stringify(this.entity)) }   addTaxonbar(qnum) { var catreg = new RegExp(/((\[\[Category:\s*[^\]]+\]\]|{{DEFAULTSORT:\s*[^}]+}}|{{Uncategorized[^}]*}}) *\n?)+/g); var catMatch = this.markup.match(catreg); if (catMatch && catMatch.length > 0) { var lastMatch = catMatch[catMatch.length - 1]; console.log('lm="' + lastMatch + '"'); this.markup = this.markup.replace(lastMatch, '\n\n' + lastMatch); } else { console.log('test'); var stbreg = new RegExp(/\{\{[^}].*-stub\}\}/gm); var stbMatch = this.markup.match(stbreg); if (stbMatch && stbMatch.length > 0) { var frstMatch = stbMatch[0]; alert(frstMatch); this.markup = this.markup.replace(frstMatch, '\n\n' + frstMatch.trim + '\n\n'); console.log(this.markup); } else { console.log('How to add taxonbar?'); alert('How to add taxonbar?'); }       }        $('body').append(            '' +            ' ' +            '' +            '' +            '' +            '' +            '' +            '' +            '' +            ' ') $('form#tbxlzr [name=wpTextbox1]').text(this.markup.replace(/\n\{\{TaxonIds\|[^}]*\}\}/, '')) $('form#tbxlzr [name=wpSummary]').val('+ taxonbar from=" + qnum + "") $('#tbxlzrsmit').click; } } $.when(mw.loader.using([ 'mediawiki.api', 'mediawiki.util', 'mediawiki.ForeignApi', 'mediawiki.cookie', 'jquery.textSelection', 'jquery.ui' ]), $.ready).then( => {   window.taxoboxalyzer = new taxoboxalyzer });