Form:AutRecord e MediaWiki:MarcEditorDynamicLinks.js: mudanças entre as páginas

De Wikincat
(Diferenças entre páginas)
Ir para navegação Ir para pesquisar
m (Substituição de texto - "textarea with autocomplete" por "combobox")
 
Sem resumo de edição
 
Linha 1: Linha 1:
// Author: @vitorsilverio
<noinclude>
// Author: @jaideraf
/*jshint esversion: 6 */
function main() {
let tag = '';
let tagFromDropdown = '';
function createMarcFieldHelpLink() {
const tagInputs = document.body.querySelectorAll('.tagInput');
tagInputs.forEach((elem) => {
const marcFieldHelpLink = document.createElement('a');
marcFieldHelpLink.setAttribute('target', '_blank');
marcFieldHelpLink.innerText = '(?)';
const marcFieldHelpLinkClass = elem.closest('table')
.querySelector('.marcFieldHelpLink');
marcFieldHelpLinkClass.innerHTML = "";
marcFieldHelpLinkClass.appendChild(marcFieldHelpLink);
// find the tag value from the chosen dropdown
marcFieldHelpLinkClass.addEventListener('mouseover', (event) => {
tagFromDropdown = event.target.closest('.instanceMain')
.querySelector('.oo-ui-inputWidget-input')
.getAttribute('title') || '00x';
tagFromDropdown = tagFromDropdown.substring(0, 3);
marcFieldHelpLink.setAttribute(
'title',
`Documentação do campo ${tagFromDropdown}`
);
// build the URL
if (window.location.href.match(/A\d{6}/)
|| window.location.href.match(/AutRecord/)) {
marcFieldHelpLink.setAttribute(
'href',
`http://marc.febab.org/a${tagFromDropdown}`
);
} else {
marcFieldHelpLink.setAttribute(
'href',
`https://www.loc.gov/marc/bibliographic/bd${tagFromDropdown}.html`
);
}
});
});
}
function createAuthorityLinks() {
const inputs = document.body.querySelectorAll('.instanceMain div table .oo-ui-inputWidget-input');
inputs.forEach((elem) => {
const authorityLink = document.createElement('a');
authorityLink.setAttribute('title', 'Abre uma nova aba para criar ou editar um registro de autoridade');
authorityLink.setAttribute('target', '_blank');
authorityLink.innerText = 'Criar registro de autoridade';
authorityLink.style.display = 'none';
const createAuthorityLink = elem.closest('table')
.querySelector('.createAuthorityLink');
createAuthorityLink.innerHTML = "";
createAuthorityLink.appendChild(authorityLink);
const pattern1 = /\$0\sA\d{6}/;
const pattern2 = /\$0\s\(BN\)\d{9}/;
elem.addEventListener('focusout', () => {
// if already recorded
if (pattern1.test(elem.value)) {
// build the URL for Wikincat aut record edit
authorityLink.innerText = 'Editar autoridade';
authorityLink.setAttribute(
'href',
`/wiki/Special:FormEdit/AutRecord/Autoridade:${
elem.value.match(/A\d{6}/)}`
);
} else if (pattern2.test(elem.value)) {
// build the URL for BN aut record view
authorityLink.innerText = 'Ver registro de autoridade na BN';
authorityLink.setAttribute(
'href',
`http://acervo.bn.gov.br/sophia_web/autoridade/detalhe/${
elem.value.match(/\d{9}/)}`
);
} else {
// find the tag value from the chosen dropdown
tagFromDropdown = elem.closest('.instanceMain')
.querySelector('.oo-ui-inputWidget-input')
.getAttribute('title') || '00x';
tagFromDropdown = tagFromDropdown.substring(0, 3);
// find the tag value from checked radio button
const tagFromRadio = elem.closest('.instanceMain')
.querySelector('input[origname=\'Field[authorityType]\']:checked')
.value;
const authorityTypes = {
'Pessoa': '100',
'Entidade coletiva': '110',
'Evento': '111',
'Título uniforme': '130',
'Tópico': '150',
'Local': '151'
};
if (tagFromRadio in authorityTypes) {
tag = authorityTypes[tagFromRadio];
}
// declare the indicators default values
let ind1 = elem.closest('.instanceMain')
.querySelector('select[origname=\'Field[ind1]\'] option:checked')
.value;
let ind2 = elem.closest('.instanceMain')
.querySelector('select[origname=\'Field[ind2]\'] option:checked')
.value;
// declare the 008 field default values
let directOrIndirectGeogSubdiv = ''; // 06
let kindOfRecord = ''; // 09
let descriptiveCatalogingRules = 'c'; // 10
let subjectHeadingSystem = 'n'; // 11
let typeOfSeries = 'n'; // 12
let numberedOrUnnumberedSeries = 'n'; // 13
let headingUseMainOrAddedEntry = 'a'; // 14
let headingUseSubjectAddedEntry = 'a'; // 15
let headingUseSeriesAddedEntry = 'b'; // 16
let typeOfSubjectSubdivision = 'n'; // 17
let undifferentiatedPersonalName = 'n'; // 32
let levelOfEstablishment = 'a'; // 33
// set the 008 field and indicadors specific values
if (tag === '100') {
undifferentiatedPersonalName = 'a';
ind2 = '';
}
if (tag === '110') {
// in case of autocomplete of 260
if (tagFromDropdown === '260') {
directOrIndirectGeogSubdiv = 'n';
kindOfRecord = 'b';
headingUseMainOrAddedEntry = 'b';
headingUseSubjectAddedEntry = 'b';
levelOfEstablishment = 'n';
ind1 = '1';
}
ind2 = '';
}
if (tag === '111') {
ind1 = '2';
ind2 = '';
}
if (tag === '130') {
typeOfSeries = 'a';
numberedOrUnnumberedSeries = 'b';
headingUseSeriesAddedEntry = 'a';
if (tagFromDropdown === '130'
|| tagFromDropdown === '630'
|| tagFromDropdown === '730') {
ind2 = ind1; // an inverted value happens here, see and
ind1 = ''; // compare bib. and auth. 130 MARC definitions
}
ind1 = '';
}
if (tag === '150' || tag === '151') {
descriptiveCatalogingRules = 'n';
subjectHeadingSystem = 'z';
headingUseMainOrAddedEntry = 'b';
ind1 = ''; // 150 and 151 indicators must be empty in
ind2 = ''; // authority MARC records
if (tag === '151') {
typeOfSubjectSubdivision = 'd';
}
}
// build the URL
const autRecordParams = {
AutRecord: {
directOrIndirectGeogSubdiv,
kindOfRecord,
descriptiveCatalogingRules,
subjectHeadingSystem,
typeOfSeries,
numberedOrUnnumberedSeries,
headingUseMainOrAddedEntry,
headingUseSubjectAddedEntry,
headingUseSeriesAddedEntry,
typeOfSubjectSubdivision,
undifferentiatedPersonalName,
levelOfEstablishment
},
Field: {
'1': {
tag: '040',
data: '$a BR-FlWIK $b por $c BR-FlWIK $d BR-FlUSC'
},
'2': {
tag,
ind1,
ind2,
data: elem.value
},
'3': {
tag: '670',
data: '$a '
}
}
};
const url = new URL(`${window.location.origin}/wiki/Special:FormEdit/AutRecord`);
// function to transform a 3rd level object to URL query strings
const makeUrlParams = (obj) => {
for (const [key, value] of Object.entries(obj)) {
if (typeof value === 'object') {
for (const [key2, value2] of Object.entries(value)) {
if (typeof value2 === 'object') {
for (const [key3, value3] of Object.entries(value2)) {
url.searchParams.set(`${key}[${key2}][${key3}]`, value3);
}
} else {
url.searchParams.set(`${key}[${key2}]`, value2);
}
}
} else {
url.searchParams.set(key, value);
}
}
};
makeUrlParams(autRecordParams);
authorityLink.innerText = 'Criar registro de autoridade';
authorityLink.setAttribute('href', url.pathname + url.search);
}
authorityLink.style.display = '';
});
});
}
function rmCarriageReturn() {
const textareas = document.body.querySelectorAll('textarea');
textareas.forEach((textarea) => {
const element = textarea;
element.value = element.value.replace('&#13;', '');
});
}
function rmHtmlTags() {
const textareas = document.body.querySelectorAll('textarea');
textareas.forEach((textarea) => {
const element = textarea;
element.value = element.value.replace(/<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>/g, '');
});
}
function rmTxtFromHiddenFields() {
const spans = document.body.querySelectorAll('span.hiddenByPF');
spans.forEach((elem) => {
elem.querySelectorAll('.input.oo-ui-inputWidget-input').forEach((input) => {
const element = input;
element.value = '';
});
elem.querySelectorAll('textarea').forEach((input) => {
const element = input;
element.value = '';
});
});
}
function normalizeInput() {
const instanceMains = document.body.querySelectorAll('.instanceMain div table');
instanceMains.forEach((instanceMain) => {
instanceMain.querySelectorAll('.oo-ui-inputWidget-input').forEach((input) => {
const normalizedInput = input;
normalizedInput.value = normalizedInput.value
// "$a Bar \n$b Baz" > " $a Bar $b Baz"
.replace(/\s*(\$[a-z0-8])\s*/g, ' $1 ')
// "$a Bar\nFoo" > "$a Bar Foo" ou "$a Bar Foo" > "$a Bar Foo"
.replace(/\n|\s\s+|\t/g, ' ')
// replace "|" by "%7C" (Ex.: http://viaf.org/processed/WKP|Q2484404)
.replace('|', '%7C');
});
instanceMain.querySelectorAll('textarea').forEach((textarea) => {
const normalizedInput = textarea;
textarea.value = normalizedInput.value
// "$a Bar \n$b Baz" > " $a Bar $b Baz"
.replace(/\s*(\$[a-z0-8])\s*/g, ' $1 ')
// "$a Bar\nFoo" > "$a Bar Foo" ou "$a Bar Foo" > "$a Bar Foo"
.replace(/\n|\s\s+|\t/g, ' ')
// replace "|" by "%7C" (Ex.: http://viaf.org/processed/WKP|Q2484404)
.replace('|', '%7C');
});
});
}
// calls main functions
createMarcFieldHelpLink();
createAuthorityLinks();
rmCarriageReturn();
rmHtmlTags();
// Como instâncias do formulário são criadas pelo botão "Adicionar campo",
// é necessário observar o DOM a partir da classe ".multipleTemplateList".
// Toda vez que o DOM é alterado (mais especificamente, quando uma nova
// child de ".multipleTemplateList" é criada), as funções
// createMarcFieldHelpLink() e createAuthorityLinks() são novamente chamadas.
// https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
// create an observer instance
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
const newNodes = mutation.addedNodes; // DOM NodeList
if (newNodes.length !== 0) { // if there are new nodes added
createMarcFieldHelpLink();
createAuthorityLinks();
}
});
});
// select the target node
const target = document.querySelector('.multipleTemplateList');
// configuration of the observer
const config = {
childList: true,
attributes: false,
subtree: false,
};
// pass in the target node, as well as the observer options
observer.observe(target, config);


// when clicking save...
{{#formlink:form=AutRecord|link text=Criar registro de autoridade|link type=button}}
const saveBtn = document.body.querySelector('#wpSave');
saveBtn.addEventListener('click', () => {
observer.disconnect();
// rmTxtFromHiddenFields();
// rmCarriageReturn();
// rmHtmlTags();
// normalizeInput();
});
// when clicking adding field...
const addBtn = document.body.querySelector('.multipleTemplateAdder');
addBtn.addEventListener('click', () => {
setTimeout(createMarcFieldHelpLink, 1000);
console.log('teste');
});
}
if (document.readyState === 'complete' || (document.readyState !== 'loading')) {
main();
} else {
document.addEventListener('DOMContentLoaded', main);
}


// for no obvious reason to me, the first call to the "main" function is not
</noinclude><includeonly>
// occurring, so wait 3 seconds and call it anyway.
<div id="wikiPreview" style="display: none; padding-bottom: 25px; margin-bottom: 25px; border-bottom: 1px solid #AAAAAA;"></div>
setTimeout(main, 3000);
{{{info|page name=Authority:A<unique number;start=000001>|create title=Criar|edit title=Editar}}}
{{{for template|AutRecord}}} <!-- Date entered on file precisa ficar fora da area collapsible para funcionar --> {{{field|dateEnteredOnFile|input type=text|default={{#timel:ymd}}|hidden}}}
<html>
<div class="wrap-collapsible">
<input id="collapsible" class="toggle" type="checkbox">
<label for="collapsible" class="lbl-toggle" tabindex="1"></html>Opções do '''Líder'''<span style="float: right;">{{#info:[http://www.loc.gov/marc/authority/adleader.html ⇾ Documentação do Líder]<br>
[https://docs.fabricioassumpcao.com/marcbrowser/ ⇾ '''marc'''browser]}}<html></span></label>
<div class="collapsible-content">
<div class="content-inner"></html>
{| class="wikincatTable"
|-
| Status do registro (05): || {{{field|recordStatus|input type=combobox|size=50|maxlength=1|values=a,c,d,n,o,s,x|default=n|mapping template=AutRecord/leader/recordStatus}}}
|-
| Nível de codificação (17): || {{{field|encodingLevel|input type=combobox|size=50|maxlength=1|values=n,o|default=n|mapping template=AutRecord/leader/encodingLevel}}}
|-
| Política de pontuação (18): || {{{field|punctuationPolicy|input type=combobox|size=50|maxlength=1|values= ,c,i,u|default=i|mapping template=AutRecord/leader/punctuationPolicy}}}
|}
<html>
</div>
</div>
</div>
<div class="wrap-collapsible">
<input id="collapsible2" class="toggle" type="checkbox">
<label for="collapsible2" class="lbl-toggle" tabindex="8"></html>Opções do '''Campo 008'''<span style="float: right;">{{#info: [http://www.loc.gov/marc/authority/ad008.html Documentação do campo 008]}}<html></span></label>
<div class="collapsible-content">
<div class="content-inner"></html>
{| class="wikincatTable"
|-
| Subdivisão geográfica direta ou indireta (06): || {{{field|directOrIndirectGeogSubdiv|input type=combobox|size=50|maxlength=1|values= ,d,i,n|default= |mapping template=AutRecord/field008/directOrIndirectGeogSubdiv}}}
|-
| Tipo de registro (09): || {{{field|kindOfRecord|input type=combobox|size=50|maxlength=1|values=a,b,c,d,e,f,g|default=a|mapping template=AutRecord/field008/kindOfRecord}}}
|-
| Regras de catalogação descritiva (10): || {{{field|descriptiveCatalogingRules|input type=combobox|size=50|maxlength=4|values=a,b,c,d,z,n|default=n|mapping template=AutRecord/field008/descriptiveCatalogingRules}}}
|-
| Sistema de pontos de acesso de assunto/tesauro (11): || {{{field|subjectHeadingSystem|input type=combobox|size=50|maxlength=1|values=a,b,c,d,k,n,r,s,v,z|default=n|mapping template=AutRecord/field008/subjectHeadingSystem}}}
|-
| Tipo de série (12): || {{{field|typeOfSeries|input type=combobox|size=50|maxlength=1|values=a,b,c,n,z|default=n|mapping template=AutRecord/field008/typeOfSeries}}}
|-
| Série numerada ou não numerada (13): || {{{field|numberedOrUnnumberedSeries|input type=combobox|size=50|maxlength=1|values=a,b,c,n|default=n|mapping template=AutRecord/field008/numberedOrUnnumberedSeries}}}
|-
| Uso do ponto de acesso autorizado como principal ou secundário (14): || {{{field|headingUseMainOrAddedEntry|input type=combobox|size=50|maxlength=1|values=a,b|default=a|mapping template=AutRecord/field008/headingUseMainOrAddedEntry}}}
|-
| Uso do ponto de acesso autorizado como ponto de acesso de assunto (15): || {{{field|headingUseSubjectAddedEntry|input type=combobox|size=50|maxlength=1|values=a,b|default=a|mapping template=AutRecord/field008/headingUseSubjectAddedEntry}}}
|-
| Uso do ponto de acesso autorizado como ponto de acesso de série (16): || {{{field|headingUseSeriesAddedEntry|input type=combobox|size=50|maxlength=1|values=a,b|default=b|mapping template=AutRecord/field008/headingUseSeriesAddedEntry}}}
|-
| Tipo de subdivisão de assunto (17): || {{{field|typeOfSubjectSubdivision|input type=combobox|size=50|maxlength=1|values=a,b,c,d,e,n|default=n|mapping template=AutRecord/field008/typeOfSubjectSubdivision}}}
|-
| Tipo de agência governamental (28): || {{{field|typeOfGovernmentAgency|input type=combobox|size=50|maxlength=1|values= ,a,c,f,i,l,m,o,s,u,z|default= |mapping template=AutRecord/field008/typeOfGovernmentAgency}}}
|-
| Remissivas (29): || {{{field|referenceEvaluation|input type=combobox|size=50|maxlength=1|values=a,b,n|default=n|mapping template=AutRecord/field008/referenceEvaluation}}}
|-
| Nome pessoal indiferenciável (32): || {{{field|undifferentiatedPersonalName|input type=combobox|size=50|maxlength=1|values=a,b,n|default=n|mapping template=AutRecord/field008/undifferentiatedPersonalName}}}
|-
| Nível de estabelecimento (33): || {{{field|levelOfEstablishment|input type=combobox|size=50|maxlength=1|values=a,b,c,d,n|default=a|mapping template=AutRecord/field008/levelOfEstablishment}}}
|-
| Registro modificado (38): || {{{field|modifiedRecord|input type=combobox|size=50|maxlength=1|values= ,s,x|default= |mapping template=AutRecord/field008/modifiedRecord}}}
|-
| Fonte da catalogação (39): || {{{field|catalogingSource|input type=combobox|size=50|maxlength=1|values= ,c,d,u|default=d|mapping template=AutRecord/field008/catalogingSource}}}
|}<html>
</div>
</div>
</div>
</html>
{{{end template}}}
{{{for template|Field|multiple|add button text=Adicionar campo|minimum instances=1|displayed fields when minimized=tag,ind1,ind2,data,authorityData100,authorityData110,authorityData111,authorityData130,authorityData150,authorityData151}}}
{| class="formtable"
! Campo: <span class="marcFieldHelpLink"></span>
| {{{field|tag|mandatory|input type=combobox|size=105|delimiter=,|values=010,024,035,040,043,045,100,110,111,130,148,150,151,190,191,260,360,400,410,411,430,448,450,451,500,510,511,530,548,550,551,643,663,664,667,670,672,675,677,680,750,856|mapping template=AutRecord/tags|class=tagInput}}}
|-
! Autoridade:
| {{{field|authorityType|mandatory|input type=radiobutton|values=Nenhuma,Pessoa,Entidade coletiva,Evento,Título uniforme,Tópico,Local|show on select=Nenhuma=>noAuthority;Pessoa=>personalName;Entidade coletiva=>corporateName;Evento=>meetingName;Título uniforme=>uniformTitle;Tópico=>topicalTerm;Local=>geographicName|default=Nenhuma}}}
|-
! Indicadores:
| {{{field|ind1|input type=dropdown|values=#,0,1,2,3,4,5,6,7,8,9|default=#|existing values only|mandatory}}} {{{field|ind2|input type=dropdown|values=#,0,1,2,3,4,5,6,7,8,9|default=#|existing values only|mandatory}}}
|}
<div id="noAuthority">
{| class="formtable"
! Subcampos:
| {{{field|data|input type=textarea|rows=3|cols=75|autogrow|placeholder=$a ... $b ... $c ...|class=noAuthority}}}
|}
</div>
<div id="personalName">
{| class="formtable"
! Subcampos:
| {{{field|authorityData100|input type=combobox|rows=3|cols=75|autogrow|placeholder=$a ... $q (...), $d ...|remote autocompletion|values from property=Personal name|class=personalName has-authority-control}}}
|-
!
| <span class="createAuthorityLink"></span>
|}
</div>
<div id="corporateName">
{| class="formtable"
! Subcampos:
| {{{field|authorityData110|input type=combobox|rows=3|cols=75|autogrow|placeholder=$a ... $b ...|remote autocompletion|values from property=Corporate name|class=corporateName has-authority-control}}}
|-
!
| <span class="createAuthorityLink"></span>
|}
</div>
<div id="meetingName">
{| class="formtable"
! Subcampos:
| {{{field|authorityData111|input type=combobox|rows=3|cols=75|autogrow|placeholder=$a ... ($n ... : $d ... : $c ...)|remote autocompletion|values from property=Meeting name|class=meetingName has-authority-control}}}
|-
!
| <span class="createAuthorityLink"></span>
|}
</div>
<div id="uniformTitle">
{| class="formtable"
! Subcampos:
| {{{field|authorityData130|input type=combobox|rows=3|cols=75|autogrow|placeholder=$a ...|remote autocompletion|values from property=Uniform title|class=uniformTitle has-authority-control}}}
|-
!
| <span class="createAuthorityLink"></span>
|}
</div>
<div id="topicalTerm">
{| class="formtable"
! Subcampos:
| {{{field|authorityData150|input type=combobox|rows=3|cols=75|autogrow|placeholder=$a ... $x ... $z ... $y ...|remote autocompletion|values from property=Topical term|class=topicalTerm has-authority-control}}}
|-
!
| <span class="createAuthorityLink"></span>
|}
</div>
<div id="geographicName">
{| class="formtable"
! Subcampos:
| {{{field|authorityData151|input type=combobox|rows=3|cols=75|autogrow|placeholder=$a ... $x ...|remote autocompletion|values from property=Geographic name|class=geographicName has-authority-control}}}
|-
!
| <span class="createAuthorityLink"></span>
|}
</div>

{{{end template}}}
{{{for template|EndOfRecord}}}
{{{end template}}}


----


{{{standard input|save|label=Gravar alterações}}} * '''Atenção''': Após gravar, não se esqueça de clicar em "'''Mais'''" > "'''Atualizar'''" no menu superior (ao lado da caixa de busca) | {{{standard input|cancel}}}
<html>
<script src="/w/index.php?title=MediaWiki:MarcEditorDynamicLinks.js&action=raw&ctype=text/javascript"></script>
<script src="/w/index.php?title=MediaWiki:CollapsibleBySpaceOrEnter.js&action=raw&ctype=text/javascript"></script>
</html></includeonly>

Edição das 15h02min de 14 de março de 2024

// Author: @vitorsilverio
// Author: @jaideraf
/*jshint esversion: 6 */
function main() {
    let tag = '';
    let tagFromDropdown = '';
  
    function createMarcFieldHelpLink() {
      const tagInputs = document.body.querySelectorAll('.tagInput');
      tagInputs.forEach((elem) => {
        const marcFieldHelpLink = document.createElement('a');
        marcFieldHelpLink.setAttribute('target', '_blank');
        marcFieldHelpLink.innerText = '(?)';
  
        const marcFieldHelpLinkClass = elem.closest('table')
          .querySelector('.marcFieldHelpLink');
        marcFieldHelpLinkClass.innerHTML = "";  
        marcFieldHelpLinkClass.appendChild(marcFieldHelpLink);
  
        // find the tag value from the chosen dropdown
        marcFieldHelpLinkClass.addEventListener('mouseover', (event) => {
          tagFromDropdown = event.target.closest('.instanceMain')
            .querySelector('.oo-ui-inputWidget-input')
            .getAttribute('title') || '00x';
          tagFromDropdown = tagFromDropdown.substring(0, 3);
          marcFieldHelpLink.setAttribute(
            'title',
            `Documentação do campo ${tagFromDropdown}`
          );
          // build the URL
          if (window.location.href.match(/A\d{6}/)
                      || window.location.href.match(/AutRecord/)) {
            marcFieldHelpLink.setAttribute(
              'href',
              `http://marc.febab.org/a${tagFromDropdown}`
            );
          } else {
            marcFieldHelpLink.setAttribute(
              'href',
              `https://www.loc.gov/marc/bibliographic/bd${tagFromDropdown}.html`
            );
          }
        });
      });
    }
  
    function createAuthorityLinks() {
      const inputs = document.body.querySelectorAll('.instanceMain div table .oo-ui-inputWidget-input');
      inputs.forEach((elem) => {
        const authorityLink = document.createElement('a');
        authorityLink.setAttribute('title', 'Abre uma nova aba para criar ou editar um registro de autoridade');
        authorityLink.setAttribute('target', '_blank');
        authorityLink.innerText = 'Criar registro de autoridade';
        authorityLink.style.display = 'none';
  
        const createAuthorityLink = elem.closest('table')
          .querySelector('.createAuthorityLink');
        createAuthorityLink.innerHTML = "";  
        createAuthorityLink.appendChild(authorityLink);
  
        const pattern1 = /\$0\sA\d{6}/;
        const pattern2 = /\$0\s\(BN\)\d{9}/;
  
        elem.addEventListener('focusout', () => {
          // if already recorded
          if (pattern1.test(elem.value)) {
            // build the URL for Wikincat aut record edit
            authorityLink.innerText = 'Editar autoridade';
            authorityLink.setAttribute(
              'href',
              `/wiki/Special:FormEdit/AutRecord/Autoridade:${
                elem.value.match(/A\d{6}/)}`
            );
          } else if (pattern2.test(elem.value)) {
            // build the URL for BN aut record view
            authorityLink.innerText = 'Ver registro de autoridade na BN';
            authorityLink.setAttribute(
              'href',
              `http://acervo.bn.gov.br/sophia_web/autoridade/detalhe/${
                elem.value.match(/\d{9}/)}`
            );
          } else {
            // find the tag value from the chosen dropdown
            tagFromDropdown = elem.closest('.instanceMain')
              .querySelector('.oo-ui-inputWidget-input')
              .getAttribute('title') || '00x';
            tagFromDropdown = tagFromDropdown.substring(0, 3);
            // find the tag value from checked radio button
  
            const tagFromRadio = elem.closest('.instanceMain')
              .querySelector('input[origname=\'Field[authorityType]\']:checked')
              .value;
  
            const authorityTypes = {
              'Pessoa': '100',
              'Entidade coletiva': '110',
              'Evento': '111',
              'Título uniforme': '130',
              'Tópico': '150',
              'Local': '151'
            };
  
            if (tagFromRadio in authorityTypes) {
              tag = authorityTypes[tagFromRadio];
            }
  
            // declare the indicators default values
            let ind1 = elem.closest('.instanceMain')
              .querySelector('select[origname=\'Field[ind1]\'] option:checked')
              .value;
            let ind2 = elem.closest('.instanceMain')
              .querySelector('select[origname=\'Field[ind2]\'] option:checked')
              .value;
  
            // declare the 008 field default values
            let directOrIndirectGeogSubdiv = ''; // 06
            let kindOfRecord = ''; // 09
            let descriptiveCatalogingRules = 'c'; // 10
            let subjectHeadingSystem = 'n'; // 11
            let typeOfSeries = 'n'; // 12
            let numberedOrUnnumberedSeries = 'n'; // 13
            let headingUseMainOrAddedEntry = 'a'; // 14
            let headingUseSubjectAddedEntry = 'a'; // 15
            let headingUseSeriesAddedEntry = 'b'; // 16
            let typeOfSubjectSubdivision = 'n'; // 17
            let undifferentiatedPersonalName = 'n'; // 32
            let levelOfEstablishment = 'a'; // 33
  
            // set the 008 field and indicadors specific values
            if (tag === '100') {
              undifferentiatedPersonalName = 'a';
              ind2 = '';
            }
            if (tag === '110') {
              // in case of autocomplete of 260
              if (tagFromDropdown === '260') {
                directOrIndirectGeogSubdiv = 'n';
                kindOfRecord = 'b';
                headingUseMainOrAddedEntry = 'b';
                headingUseSubjectAddedEntry = 'b';
                levelOfEstablishment = 'n';
                ind1 = '1';
              }
              ind2 = '';
            }
            if (tag === '111') {
              ind1 = '2';
              ind2 = '';
            }
            if (tag === '130') {
              typeOfSeries = 'a';
              numberedOrUnnumberedSeries = 'b';
              headingUseSeriesAddedEntry = 'a';
              if (tagFromDropdown === '130'
                              || tagFromDropdown === '630'
                              || tagFromDropdown === '730') {
                ind2 = ind1; // an inverted value happens here, see and
                ind1 = ''; // compare bib. and auth. 130 MARC definitions
              }
              ind1 = '';
            }
            if (tag === '150' || tag === '151') {
              descriptiveCatalogingRules = 'n';
              subjectHeadingSystem = 'z';
              headingUseMainOrAddedEntry = 'b';
              ind1 = ''; // 150 and 151 indicators must be empty in
              ind2 = ''; // authority MARC records
              if (tag === '151') {
                typeOfSubjectSubdivision = 'd';
              }
            }
            // build the URL
            const autRecordParams = {
              AutRecord: {
                directOrIndirectGeogSubdiv,
                kindOfRecord,
                descriptiveCatalogingRules,
                subjectHeadingSystem,
                typeOfSeries,
                numberedOrUnnumberedSeries,
                headingUseMainOrAddedEntry,
                headingUseSubjectAddedEntry,
                headingUseSeriesAddedEntry,
                typeOfSubjectSubdivision,
                undifferentiatedPersonalName,
                levelOfEstablishment
              },
              Field: {
                '1': {
                  tag: '040',
                  data: '$a BR-FlWIK $b por $c BR-FlWIK $d BR-FlUSC'
                },
                '2': {
                  tag,
                  ind1,
                  ind2,
                  data: elem.value
                },
                '3': {
                  tag: '670',
                  data: '$a '
                }
              }
            };
  
            const url = new URL(`${window.location.origin}/wiki/Special:FormEdit/AutRecord`);
            // function to transform a 3rd level object to URL query strings
            const makeUrlParams = (obj) => {
              for (const [key, value] of Object.entries(obj)) {
                if (typeof value === 'object') {
                  for (const [key2, value2] of Object.entries(value)) {
                    if (typeof value2 === 'object') {
                      for (const [key3, value3] of Object.entries(value2)) {
                        url.searchParams.set(`${key}[${key2}][${key3}]`, value3);
                      }
                    } else {
                      url.searchParams.set(`${key}[${key2}]`, value2);
                    }
                  }
                } else {
                  url.searchParams.set(key, value);
                }
              }
            };
            makeUrlParams(autRecordParams);
            authorityLink.innerText = 'Criar registro de autoridade';
            authorityLink.setAttribute('href', url.pathname + url.search);
          }
          authorityLink.style.display = '';
        });
      });
    }
  
    function rmCarriageReturn() {
      const textareas = document.body.querySelectorAll('textarea');
      textareas.forEach((textarea) => {
        const element = textarea;
        element.value = element.value.replace('&#13;', '');
      });
    }
  
    function rmHtmlTags() {
      const textareas = document.body.querySelectorAll('textarea');
      textareas.forEach((textarea) => {
        const element = textarea;
        element.value = element.value.replace(/<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>/g, '');
      });
    }
  
    function rmTxtFromHiddenFields() {
      const spans = document.body.querySelectorAll('span.hiddenByPF');
      spans.forEach((elem) => {
        elem.querySelectorAll('.input.oo-ui-inputWidget-input').forEach((input) => {
          const element = input;
          element.value = '';
        });
        elem.querySelectorAll('textarea').forEach((input) => {
          const element = input;
          element.value = '';
        });
      });
    }
  
    function normalizeInput() {
      const instanceMains = document.body.querySelectorAll('.instanceMain div table');
      instanceMains.forEach((instanceMain) => {
          instanceMain.querySelectorAll('.oo-ui-inputWidget-input').forEach((input) => {
              const normalizedInput = input;
              normalizedInput.value = normalizedInput.value
              // "$a   Bar   \n$b    Baz" > " $a Bar $b Baz"
              .replace(/\s*(\$[a-z0-8])\s*/g, ' $1 ')
              // "$a Bar\nFoo" > "$a Bar Foo" ou "$a Bar  Foo" > "$a Bar Foo"
              .replace(/\n|\s\s+|\t/g, ' ')
              // replace "|" by "%7C" (Ex.: http://viaf.org/processed/WKP|Q2484404)
              .replace('|', '%7C');
          });
          instanceMain.querySelectorAll('textarea').forEach((textarea) => {
              const normalizedInput = textarea;
              textarea.value = normalizedInput.value
              // "$a   Bar   \n$b    Baz" > " $a Bar $b Baz"
              .replace(/\s*(\$[a-z0-8])\s*/g, ' $1 ')
              // "$a Bar\nFoo" > "$a Bar Foo" ou "$a Bar  Foo" > "$a Bar Foo"
              .replace(/\n|\s\s+|\t/g, ' ')
              // replace "|" by "%7C" (Ex.: http://viaf.org/processed/WKP|Q2484404)
              .replace('|', '%7C');
          });
      });
    }
  
    // calls main functions
    createMarcFieldHelpLink();
    createAuthorityLinks();
    rmCarriageReturn();
    rmHtmlTags();
  
    // Como instâncias do formulário são criadas pelo botão "Adicionar campo",
    // é necessário observar o DOM a partir da classe ".multipleTemplateList".
    // Toda vez que o DOM é alterado (mais especificamente, quando uma nova
    // child de ".multipleTemplateList" é criada), as funções
    // createMarcFieldHelpLink() e createAuthorityLinks() são novamente chamadas.
    // https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
  
    // create an observer instance
    const observer = new MutationObserver((mutations) => {
      mutations.forEach((mutation) => {
        const newNodes = mutation.addedNodes; // DOM NodeList
        if (newNodes.length !== 0) { // if there are new nodes added
          createMarcFieldHelpLink();
          createAuthorityLinks();
        }
      });
    });
  
    // select the target node
    const target = document.querySelector('.multipleTemplateList');
  
    // configuration of the observer
    const config = {
      childList: true,
      attributes: false,
      subtree: false,
    };
  
    // pass in the target node, as well as the observer options
    observer.observe(target, config);

    // when clicking save...
    const saveBtn = document.body.querySelector('#wpSave');
    saveBtn.addEventListener('click', () => {
        observer.disconnect();
        // rmTxtFromHiddenFields();
        // rmCarriageReturn();
        // rmHtmlTags();
        // normalizeInput();
    });
  
    // when clicking adding field...
    const addBtn = document.body.querySelector('.multipleTemplateAdder');
    addBtn.addEventListener('click', () => {
        setTimeout(createMarcFieldHelpLink, 1000);
        console.log('teste');
    });
}
  
if (document.readyState === 'complete' || (document.readyState !== 'loading')) {
main();
} else {
document.addEventListener('DOMContentLoaded', main);
}

// for no obvious reason to me, the first call to the "main" function is not 
// occurring, so wait 3 seconds and call it anyway.
setTimeout(main, 3000);