MediaWiki:MarcEditorDynamicLinks.js: mudanças entre as edições

De Wikincat
Ir para navegação Ir para pesquisar
imported>Jaideraf
(replace jquery)
imported>Jaideraf
(comparing)
Linha 5: Linha 5:
// make collapsible CSS clickable (space or enter to click)
// make collapsible CSS clickable (space or enter to click)
// from: https://alligator.io/css/collapsible/
// from: https://alligator.io/css/collapsible/
"use strict";
let myCollapsibleLabels = document.querySelectorAll(".lbl-toggle");
let myCollapsibleLabels = document.querySelectorAll(".lbl-toggle");


Array.from(myCollapsibleLabels).forEach(label => {
Array.from(myCollapsibleLabels).forEach(label => {
label.addEventListener("keydown", e => {
label.addEventListener("keydown", e => {
// 32 === spacebar
// 32 === spacebar
// 13 === enter
// 13 === enter
if (e.which === 32 || e.which === 13) {
if (e.which === 32 || e.which === 13) {
e.preventDefault();
e.preventDefault();
label.click();
label.click();
}
}
});
});
});
});
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
Linha 22: Linha 21:
let tagFromDropdown = "";
let tagFromDropdown = "";


function createMarcFieldHelpLink() {
function createMarcFieldHelpLinks() {
"use strict";
const tagInputs = document.body.querySelectorAll('.tagInput');
$(".tagInput").each(function() {
tagInputs.forEach(elem => {
const marcFieldHelpLink = document.createElement('a');
let marcFieldHelpLink = $("<a>", {
marcFieldHelpLink.setAttribute('target', '_blank');
target: "_blank",
marcFieldHelpLink.innerText = `(?)`;
text: "(?)"
});

const marcFieldHelpLinkClass = elem.closest('table').querySelector('.marcFieldHelpLink');
$(this).closest("table").find(".marcFieldHelpLink").html(marcFieldHelpLink);
marcFieldHelpLinkClass.appendChild(marcFieldHelpLink);
$(this).closest("table").find(".marcFieldHelpLink").hover(function() {


// find the tag value from the chosen dropdown
// find the tag value from the chosen dropdown
tagFromDropdown = $(this).closest(".instanceMain").find(".select2-selection__rendered").attr("title");
marcFieldHelpLinkClass.addEventListener('mouseover', event => {
tagFromDropdown = event.target.closest('.instanceMain').querySelector('.select2-selection__rendered').getAttribute('title');
tagFromDropdown = tagFromDropdown.substring(0, 3);
tagFromDropdown = tagFromDropdown.substring(0, 3);

marcFieldHelpLink.setAttribute('title',
`Documentação do campo ${tagFromDropdown}`);
// build the URL
// build the URL
marcFieldHelpLink.attr("title", "Documentação do campo " + tagFromDropdown);
if (window.location.href.match(/A\d{6}/) ||
if (window.location.href.match(/A\d{6}/) ||
window.location.href.match(/AutRecord/)) {
window.location.href.match(/AutRecord/)) {
marcFieldHelpLink.setAttribute('href', 'http://marc.febab.org/a' + tagFromDropdown);
marcFieldHelpLink.attr("href", "http://marc.febab.org/a" + tagFromDropdown);
} else {
} else {
marcFieldHelpLink.setAttribute('href', `https://www.loc.gov/marc/bibliographic/bd${tagFromDropdown}.html`);
marcFieldHelpLink.attr("href", "https://www.loc.gov/marc/bibliographic/bd" + tagFromDropdown + ".html");
}
}
});
});
Linha 50: Linha 49:


function createAuthorityLinks() {
function createAuthorityLinks() {
"use strict";
const textareas = document.body.querySelectorAll('textarea.has-authority-control');
$("textarea").each(function() {
textareas.forEach(elem => {
let authorityLink = document.createElement('a');
let authorityLink = $("<a>", {
authorityLink.setAttribute('title', 'Abre uma nova aba para criar ou editar um registro de autoridade');
title: "Abre uma nova aba para criar ou editar um registro de autoridade",
authorityLink.setAttribute('target', '_blank');
target: "_blank",
authorityLink.innerText = 'Criar autoridade';
text: "Criar autoridade"
});
authorityLink.style.display = 'none';

let createAuthorityLink = elem.closest('table').querySelector('.createAuthorityLink');

createAuthorityLink.appendChild(authorityLink);

let pattern1 = /\$0\sA\d{6}/;
let pattern1 = /\$0\sA\d{6}/;
let pattern2 = /\$0\s\(BN\)\d{9}/;
let pattern2 = /\$0\s\(BN\)\d{9}/;
authorityLink.hide();

$(this).closest("table").find(".createAuthorityLink").html(authorityLink);
elem.addEventListener('focusout', () => {
$(this).focusout(function() {
// if already recorded
// if already recorded
if (pattern1.test(elem.value)) {
if (pattern1.test($(this).val())) {
// build the URL for Wikincat aut record edit
// build the URL for Wikincat aut record edit
authorityLink.innerText = 'Editar autoridade';
authorityLink.text("Editar autoridade");
authorityLink.setAttribute('href',
authorityLink.attr("href", "/wiki/Special:FormEdit/AutRecord/Autoridade:" +
'/wiki/Special:FormEdit/AutRecord/Autoridade:' +
$(this).val().match(/A\d{6}/));
elem.value.match(/A\d{6}/));
} else if (pattern2.test($(this).val())) {
} else if (pattern2.test(elem.value)) {
// build the URL for BN aut record view
// build the URL for BN aut record view
authorityLink.text("Ver autoridade na BN");
authorityLink.innerText = 'Ver autoridade na BN';
authorityLink.attr("href", "http://acervo.bn.br/sophia_web/autoridade/detalhe/" +
authorityLink.setAttribute('href',
$(this).val().match(/\d{9}/));
} else {
'http://acervo.bn.br/sophia_web/autoridade/detalhe/' +
elem.value.match(/\d{9}/));
} else {
// find the tag value from the chosen dropdown
// find the tag value from the chosen dropdown
tagFromDropdown = elem.closest(".instanceMain")
tagFromDropdown = $(this).closest(".instanceMain")
// PageForms 4.8
// PageForms 4.8
// .find(".select2-chosen").text();
// .find(".select2-chosen").text();
// Page forms 4.9.1
// Page forms 4.9.1
.querySelector('.select2-selection__rendered')
.find(".select2-selection__rendered").attr("title");
.getAttribute('title');
tagFromDropdown = tagFromDropdown.substring(0, 3);
tagFromDropdown = tagFromDropdown.substring(0, 3);

// find the tag value from checked radio button
// find the tag value from checked radio button
let tagFromRadio = $(this).closest(".instanceMain")

let tagFromRadio = elem.closest('.instanceMain')
.find("input[origname='Field[authorityType]']:checked").val();
.querySelector("input[origname='Field[authorityType]']:checked")
.value;

let authorityTypes = {
let authorityTypes = {
"Pessoa": "100",
"Pessoa": "100",
Linha 102: Linha 92:
"Local": "151"
"Local": "151"
};
};

if (tagFromRadio in authorityTypes) {
if (tagFromRadio in authorityTypes) {
tag = authorityTypes[tagFromRadio];
tag = authorityTypes[tagFromRadio];
Linha 108: Linha 97:


// declare the indicators default values
// declare the indicators default values
let ind1 = elem.closest(".instanceMain")
let ind1 = $(this).closest(".instanceMain")
.querySelector("select[origname='Field[ind1]'] option:checked")
.find("select[origname='Field[ind1]'] option:selected").val();
.value;
let ind2 = $(this).closest(".instanceMain")
let ind2 = elem.closest(".instanceMain")
.find("select[origname='Field[ind2]'] option:selected").val();
.querySelector("select[origname='Field[ind2]'] option:checked")
.value;


// declare the 008 field default values
// declare the 008 field default values
let directOrIndirectGeogSubdiv = "", // 06
let directOrIndirectGeogSubdiv = "", // 06
kindOfRecord = "", // 09
kindOfRecord = "", // 09
descriptiveCatalogingRules = "c", // 10
descriptiveCatalogingRules = "c", // 10
subjectHeadingSystem = "n", // 11
subjectHeadingSystem = "n", // 11
typeOfSeries = "n", // 12
typeOfSeries = "n", // 12
numberedOrUnnumberedSeries = "n", // 13
numberedOrUnnumberedSeries = "n", // 13
headingUseMainOrAddedEntry = "a", // 14
headingUseMainOrAddedEntry = "a", // 14
headingUseSubjectAddedEntry = "a", // 15
headingUseSubjectAddedEntry= "a", // 15
headingUseSeriesAddedEntry = "b", // 16
headingUseSeriesAddedEntry = "b", // 16
typeOfSubjectSubdivision = "n", // 17
typeOfSubjectSubdivision = "n", // 17
undifferentiatedPersonalName = "n", // 32
undifferentiatedPersonalName = "n", // 32
levelOfEstablishment = "a"; // 33
levelOfEstablishment = "a"; // 33


// set the 008 field and indicadors specific values
// set the 008 field and indicadors specific values
Linha 157: Linha 144:
tagFromDropdown === "630" ||
tagFromDropdown === "630" ||
tagFromDropdown === "730") {
tagFromDropdown === "730") {
ind2 = ind1; // an inverted value happens here, see and
ind2 = ind1; // an inverted value happens here, see and
ind1 = ""; // compare bib. and auth. 130 MARC definitions
ind1 = ""; // compare bib. and auth. 130 MARC definitions
}
}
ind1 = "";
ind1 = "";
Linha 172: Linha 159:
}
}
}
}

// build the URL
// build the URL
let autRecordSettings = {
authorityLink.text("Criar autoridade");
authorityLink.attr("href", "/wiki/Special:FormEdit/AutRecord?" +
decodeURIComponent($.param({
"AutRecord": {
"AutRecord": {
"directOrIndirectGeogSubdiv": directOrIndirectGeogSubdiv,
"directOrIndirectGeogSubdiv": directOrIndirectGeogSubdiv,
"kindOfRecord": kindOfRecord,
"kindOfRecord": kindOfRecord,
"descriptiveCatalogingRules": descriptiveCatalogingRules,
"descriptiveCatalogingRules": descriptiveCatalogingRules,
"subjectHeadingSystem": subjectHeadingSystem,
"subjectHeadingSystem": subjectHeadingSystem,
"typeOfSeries": typeOfSeries,
"typeOfSeries": typeOfSeries,
"numberedOrUnnumberedSeries": numberedOrUnnumberedSeries,
"numberedOrUnnumberedSeries": numberedOrUnnumberedSeries,
"headingUseMainOrAddedEntry": headingUseMainOrAddedEntry,
"headingUseMainOrAddedEntry": headingUseMainOrAddedEntry,
"headingUseSubjectAddedEntry": headingUseSubjectAddedEntry,
"headingUseSubjectAddedEntry": headingUseSubjectAddedEntry,
"headingUseSeriesAddedEntry": headingUseSeriesAddedEntry,
"headingUseSeriesAddedEntry": headingUseSeriesAddedEntry,
"typeOfSubjectSubdivision": typeOfSubjectSubdivision,
"typeOfSubjectSubdivision": typeOfSubjectSubdivision,
"undifferentiatedPersonalName": undifferentiatedPersonalName,
"undifferentiatedPersonalName": undifferentiatedPersonalName,
"levelOfEstablishment": levelOfEstablishment
"levelOfEstablishment": levelOfEstablishment
},
},
"Field": {
"Field": {
"1": {
"1": {
"tag": "040",
"tag": "040",
"data": "$a BR-FlWIK $b por $c BR-FlWIK $d BR-FlUSC"
"data": encodeURIComponent("$a BR-FlWIK $b por $c BR-FlWIK $d BR-FlUSC")
},
},
"2": {
"2": {
"tag": tag,
"tag": tag,
"ind1": ind1,
"ind1": encodeURIComponent(ind1),
"ind2": ind2,
"ind2": encodeURIComponent(ind2),
"data": elem.value
"data": encodeURIComponent($(this).val())
},
},
"3": {
"3": {
Linha 204: Linha 194:
}
}
}
}
};
})));

// https://stackoverflow.com/questions/278221 by Simon Staton
const stringifyParam = function (data, topLevel, keyProp) {
let string = '';
for (let key in data) {
if (keyProp && topLevel[keyProp] && topLevel[keyProp].indexOf(data[key]) !== 0) {
string += keyProp;
}
if (topLevel[key]) {
string += key;
} else {
string += '[' + key + ']';
}
if (data[key] instanceof Array) {
string += stringifyParam(data[key], topLevel, key);
} else if (data[key] instanceof Object) {
string += stringifyParam(data[key], topLevel);
} else {
string += '=' + data[key];
string += '&';
}
}
return string;
},
toParam = function (data) {
const string = stringifyParam(data, data);
return encodeURI(string.substring(0, string.length - 1).split(' ').join('+'));
};

authorityLink.innerText = 'Criar autoridade';
authorityLink.setAttribute("href", "/wiki/Special:FormEdit/AutRecord?" +
toParam(autRecordSettings));
}
}
authorityLink.style.display = '';
authorityLink.show();
});
});
});
});
}
}


function rmCarriageReturn() {
$(document).ready(function(){
"use strict";
const textareas = document.body.querySelectorAll('textarea');
// remove carriage return
textareas.forEach(elem => {
$("span.inputSpan").find("textarea").each(function() {
elem.value = elem.value.replace("&#13;", "");
let input = $(this).val();
input = input.replace("&#13;", "")
// remove any html tags
.replace(/<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>/g, "");
$(this).val(input);
});
});
}

function rmHtmlTags() {
const textareas = document.body.querySelectorAll('textarea');
textareas.forEach(elem => {
elem.value = elem.value.replace(/<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>/g, "");
});
}

function rmTxtFromHiddenTexareas() {
const textareas = document.body.querySelectorAll('span.hiddenByPF');
textareas.forEach(elem => {
elem.querySelectorAll('textarea').forEach(elem => {
elem.value = '';
});
});
}

function normalizeInput() {
const textareas = document.body.querySelectorAll('textarea');
textareas.forEach(elem => {
let normalizedInput = elem.value;
normalizedInput = elem.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");
elem.value = normalizedInput;
});
}


$(document).ready(function () {
// calls main functions
// calls main functions
createMarcFieldHelpLink();
createMarcFieldHelpLinks();
createAuthorityLinks();
createAuthorityLinks();
rmCarriageReturn();
rmHtmlTags();


// Como instâncias do formulário são criadas pelo botão "Adicionar campo",
// Como instâncias do formulário são criadas pelo botão "Adicionar campo",
Linha 296: Linha 224:


// create an observer instance
// create an observer instance
let observer = new MutationObserver(function (mutations) {
let observer = new MutationObserver(function(mutations) {
mutations.forEach(function (mutation) {
mutations.forEach(function(mutation) {
let newNodes = mutation.addedNodes; // DOM NodeList
let newNodes = mutation.addedNodes; // DOM NodeList
if (newNodes.length !== 0) { // if there are new nodes added
if(newNodes.length !== 0) { // if there are new nodes added
createMarcFieldHelpLink();
createMarcFieldHelpLinks();
createAuthorityLinks();
createAuthorityLinks();
}
}
Linha 319: Linha 247:
observer.observe(target, config);
observer.observe(target, config);


// when clicking save...
// when save, remove text form hidden textareas
$("#wpSave").click(function(){
const saveBtn = document.body.querySelector('#wpSave');
saveBtn.addEventListener('click', () => {
observer.disconnect();
observer.disconnect();
$("span.hiddenByPF").find("textarea").val("");
rmTxtFromHiddenTexareas();
$("textarea").each(function() {
rmCarriageReturn();
rmHtmlTags();
let input = $(this).val();
normalizeInput();
// normalize input
let normalizedInput = input
// "$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");
$(this).val(normalizedInput);
});
});
});

});
});

Edição das 08h47min de 9 de agosto de 2022

// Author: @vitorsilverio
// Author: @jaideraf

///////////////////////////////////////////////////////////////////
// make collapsible CSS clickable (space or enter to click)
// from: https://alligator.io/css/collapsible/
let myCollapsibleLabels = document.querySelectorAll(".lbl-toggle");

Array.from(myCollapsibleLabels).forEach(label => {
  label.addEventListener("keydown", e => {
    // 32 === spacebar
    // 13 === enter
    if (e.which === 32 || e.which === 13) {
      e.preventDefault();
      label.click();
    }
  });
});
///////////////////////////////////////////////////////////////////
let tag = "";
let tagFromDropdown = "";

function createMarcFieldHelpLinks() {
"use strict";
    $(".tagInput").each(function() {
        let marcFieldHelpLink = $("<a>", {
            target: "_blank",
            text: "(?)"
        });
        $(this).closest("table").find(".marcFieldHelpLink").html(marcFieldHelpLink);
        $(this).closest("table").find(".marcFieldHelpLink").hover(function() {

            // find the tag value from the chosen dropdown
            tagFromDropdown = $(this).closest(".instanceMain").find(".select2-selection__rendered").attr("title");
            tagFromDropdown = tagFromDropdown.substring(0, 3);

            // build the URL
            marcFieldHelpLink.attr("title", "Documentação do campo " + tagFromDropdown);
            
            if (window.location.href.match(/A\d{6}/) || 
                window.location.href.match(/AutRecord/)) {
                marcFieldHelpLink.attr("href", "http://marc.febab.org/a" + tagFromDropdown);
            } else {
            	marcFieldHelpLink.attr("href", "https://www.loc.gov/marc/bibliographic/bd" + tagFromDropdown + ".html");
            }
        });
    });
}

function createAuthorityLinks() {
"use strict";
    $("textarea").each(function() {
        let authorityLink = $("<a>", {
            title: "Abre uma nova aba para criar ou editar um registro de autoridade",
            target: "_blank",
            text: "Criar autoridade"
        });
        let pattern1 = /\$0\sA\d{6}/;
        let pattern2 = /\$0\s\(BN\)\d{9}/;
        authorityLink.hide();
        $(this).closest("table").find(".createAuthorityLink").html(authorityLink);
        $(this).focusout(function() {
            // if already recorded
            if (pattern1.test($(this).val())) {
                // build the URL for Wikincat aut record edit
                authorityLink.text("Editar autoridade");
                authorityLink.attr("href", "/wiki/Special:FormEdit/AutRecord/Autoridade:" + 
                $(this).val().match(/A\d{6}/));
            } else if (pattern2.test($(this).val())) {
            	// build the URL for BN aut record view
                authorityLink.text("Ver autoridade na BN");
                authorityLink.attr("href", "http://acervo.bn.br/sophia_web/autoridade/detalhe/" + 
                $(this).val().match(/\d{9}/));
			} else {
                // find the tag value from the chosen dropdown
                tagFromDropdown = $(this).closest(".instanceMain")
                // PageForms 4.8
                // .find(".select2-chosen").text();
                // Page forms 4.9.1
                .find(".select2-selection__rendered").attr("title");
                tagFromDropdown = tagFromDropdown.substring(0, 3);

                // find the tag value from checked radio button
                let tagFromRadio = $(this).closest(".instanceMain")
                .find("input[origname='Field[authorityType]']:checked").val();
                let 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 = $(this).closest(".instanceMain")
                .find("select[origname='Field[ind1]'] option:selected").val();
                let ind2 = $(this).closest(".instanceMain")
                .find("select[origname='Field[ind2]'] option:selected").val();

                // declare the 008 field default values
                let directOrIndirectGeogSubdiv = "", // 06
                kindOfRecord = "", // 09
                descriptiveCatalogingRules = "c", // 10
                subjectHeadingSystem = "n", // 11
                typeOfSeries = "n", // 12
                numberedOrUnnumberedSeries = "n", // 13
                headingUseMainOrAddedEntry = "a", // 14
                headingUseSubjectAddedEntry= "a", // 15
                headingUseSeriesAddedEntry = "b", // 16
                typeOfSubjectSubdivision = "n", // 17
                undifferentiatedPersonalName = "n", // 32
                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
                authorityLink.text("Criar autoridade");
                authorityLink.attr("href", "/wiki/Special:FormEdit/AutRecord?" +
                decodeURIComponent($.param({
                    "AutRecord": {
                    "directOrIndirectGeogSubdiv": directOrIndirectGeogSubdiv,
                    "kindOfRecord": kindOfRecord,
                    "descriptiveCatalogingRules": descriptiveCatalogingRules,
                    "subjectHeadingSystem": subjectHeadingSystem,
                    "typeOfSeries": typeOfSeries,
                    "numberedOrUnnumberedSeries": numberedOrUnnumberedSeries,
                    "headingUseMainOrAddedEntry": headingUseMainOrAddedEntry,
                    "headingUseSubjectAddedEntry": headingUseSubjectAddedEntry,
                    "headingUseSeriesAddedEntry": headingUseSeriesAddedEntry,
                    "typeOfSubjectSubdivision": typeOfSubjectSubdivision,
                    "undifferentiatedPersonalName": undifferentiatedPersonalName,
                    "levelOfEstablishment": levelOfEstablishment
                    },
                    "Field": {
                    	"1": {
                            "tag": "040",
                            "data": encodeURIComponent("$a BR-FlWIK $b por $c BR-FlWIK $d BR-FlUSC")
                    	},
                        "2": {
                            "tag": tag,
                            "ind1": encodeURIComponent(ind1),
                            "ind2": encodeURIComponent(ind2),
                            "data": encodeURIComponent($(this).val())
                        },
                        "3": {
                            "tag": "670",
                            "data": "$a+"
                        }
                    }
                })));
            }
            authorityLink.show();
        });
    });
}

$(document).ready(function(){
"use strict";
    // remove carriage return
    $("span.inputSpan").find("textarea").each(function() {
        let input = $(this).val();
        input = input.replace("&#13;", "")
        // remove any html tags
        .replace(/<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>/g, "");
        $(this).val(input);
    });

    // calls main functions
    createMarcFieldHelpLinks();
    createAuthorityLinks();

    // 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), a função
    // marcEditorDynamicLinks() é novamente chamada.
    // https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

    // create an observer instance
    let observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            let newNodes = mutation.addedNodes; // DOM NodeList
            if(newNodes.length !== 0) { // if there are new nodes added
                createMarcFieldHelpLinks();
                createAuthorityLinks();
            }
        });
    });

    // select the target node
    let target = document.querySelector(".multipleTemplateList");

    // configuration of the observer
    let config = {
        childList: true,
        attributes: false,
        subtree: false
    };

    // pass in the target node, as well as the observer options
    observer.observe(target, config);

    // when save, remove text form hidden textareas
    $("#wpSave").click(function(){
        observer.disconnect();
        $("span.hiddenByPF").find("textarea").val("");
        $("textarea").each(function() {
            let input = $(this).val();
            // normalize input
            let normalizedInput = input
            // "$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");
            $(this).val(normalizedInput);
        });
    });
});