Koha/koha-tmpl/intranet-tmpl/prog/en/modules/authorities/blinddetail-biblio-search.tt
Phil Ringnalda e171d5fdd3
Bug 33144: Unescape text from authority lookup for advanced editor
While the basic editor is happy with an array of subfields it can
stuff into separate fields, the advanced editor needs to get a JS
string back from the authority lookup plugin, because it is going
to just add the whole thing as text. The string has to be HTML
entity encoded, both to not allow XSS and just to not break the
window, but it needs to then be unencoded before being inserted
into the editor.

Test plan:
1. Set the system preference EnableAdvancedCatalogingEditor to
   Enable
2. Edit any Topical Term authority, and at the end of tag 150
   subfield a, add & </script>
3. Cataloging - Advanced editor
4. Press return in the editor to get a new blank line, type 650
   and press tab three times, then type Ctrl-Shift-L
5. Search for your modified authority, and click Choose
6. Verify that the tiny popup opened by the search window finished
   its job and closed itself
7. Verify that your 650 now shows as "‡aAbduction &
   </script>‡vDrama" rather than "‡aAbduction  &amp;
   &lt;/script&gt;‡vDrama."

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
2023-03-14 08:49:28 -03:00

201 lines
9.4 KiB
Text

[% USE To %]
[% SET footerjs = 1 %]
[% INCLUDE 'doc-head-open.inc' %]
<title>Authority details &rsaquo; Koha</title>
[% INCLUDE 'doc-head-close.inc' %]
</head>
<body id="auth_blinddetail-biblio-search" class="auth">
<div class="main container-fluid">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div id="loading"> <img src="[% interface | html %]/[% theme | html %]/img/spinner-small.gif" alt="" /> Loading </div>
</div>
</div>
[% MACRO jsinclude BLOCK %]
<script>
$(document).ready(function(){
[% IF rancor %]
function RancorReplaceField( new_text, ind_1, ind_2 ){
var cur_field = opener.opener.jQuery(".CodeMirror")[0].CodeMirror.marceditor.getCurrentField();
// The new_text is entity-encoded and we want decoded text
new_text = new DOMParser().parseFromString(new_text, 'text/html').body.innerText;
cur_field.setText(new_text);
[% IF update_ind1 %]cur_field.setIndicator1(ind_1);[% END %]
[% IF update_ind2 %]cur_field.setIndicator2(ind_2);[% END %]
return true;
}
[% IF ( clear ) %]
var new_line = "";
[% ELSE %]
var new_line = "
[%- FOREACH SUBFIELD_LOO IN SUBFIELD_LOOP -%]‡
[%- To.json( SUBFIELD_LOO.marc_subfield ) | html -%]
[%- FOREACH marc_value IN SUBFIELD_LOO.marc_values -%]
[%- To.json( marc_value ) | html -%]
[%- END -%]
[%- END -%]‡9[% authid | html %]";
[% END %]
RancorReplaceField( new_line, "[% indicator1 | html %]", "[% indicator2 | html %]" );
[% ELSE %]
var index_start = "[% index | html %]";
var whichfield;
try {
whichfield = opener.opener.document.getElementById(index_start);
autolinker_dialog = opener.opener.document.getElementById("autolinker_dialog");
} catch(e) {
whichfield = opener.document.getElementById(index_start);
autolinker_dialog = opener.document.getElementById("autolinker_dialog");
}
var field_start = whichfield.parentNode.parentNode.parentNode.parentNode;
// Sets the good number of form fields for the specified subfield
// Returns false if the cloning failed
function SetSubfieldNumber(subfield_name, nb) {
// Nothing to do if we only have one value
if(nb <= 1) {
return true;
}
// Find the subfield we want to clone
var re = new RegExp('^subfield' + subfield_name,'g');
var subfields = $(field_start).children('ul').children('li').filter( function() {
return this.id.match(re);
});
// Try to add as many clones as needed
try {
for(var i=0; i<nb-subfields.length; i++) {
window.opener.opener.CloneSubfield(subfields[0].getAttribute('id'),'[% advancedMARCEditor | html %]');
}
}
catch(err) {
return false;
}
return true;
}
// Fills the subfield with the values entered in argument
function SetSubfieldValues() {
// Get the arguments
var subfield_name = arguments[0];
var values = new Array();
for(var i=1; i<arguments.length; i++) {
values.push(arguments[i]);
}
// Create the correct number of form fields for all values
// If the field cloning failed, only the first value will be added to the form.
SetSubfieldNumber(subfield_name, values.length);
// Find the subfields where we will add the new values
var re = new RegExp('^subfield' + subfield_name,'g');
var subfields = $(field_start).children('ul').children('li').filter( function() {
return this.id.match(re);
});
// Add the new values to those subfields, empty the additional fields
var i=0;
subfields.each(function() {
var new_value;
if (i in values) {
new_value = values[i];
}
else {
new_value = "";
}
$(this).find('.input_marceditor').val(new_value);
i++;
});
}
function ReOrderSubField(){
var isFirst=1;
var subfield_start = $(field_start).children('ul')[0];
var first = subfield_start.firstElementChild;
[% FOREACH SUBFIELD IN SUBFIELD_LOOP %]
// grab all subfields
var subfield_name = "[% To.json(tag_number) | $raw %][% To.json(SUBFIELD.marc_subfield) | $raw %]"
var re = new RegExp('^subfield' + subfield_name,'g');
var subfields = $(subfield_start).children('li').filter( function() {return this.id.match(re); });
for (var i=0; i<subfields.length; i++){
var subfield = subfields[i];
if (isFirst ==1){
first = subfield_start.insertBefore(subfield, first);
isFirst=0;
}
else{
first = subfield_start.insertBefore(subfield, first.nextSibling);
}
}
[% END %]
}
[% UNLESS ( clear ) %]
ReOrderSubField()
[% FOREACH SUBFIELD_LOO IN SUBFIELD_LOOP %]
SetSubfieldValues(
"[% To.json(tag_number) | $raw %][% To.json(SUBFIELD_LOO.marc_subfield) | $raw %]"
[% FOREACH marc_value IN SUBFIELD_LOO.marc_values %]
,"[% To.json( marc_value ) | $raw %]"
[% END %]
);
[% END %]
var indicators = field_start.getElementsByClassName('indicator flat');
[% IF update_ind1 %]
indicators[0].value="[% indicator1 | html %]";
[% END %]
[% IF update_ind2 %]
indicators[1].value="[% indicator2 | html %]";
[% END %]
[% END %]
// browse all its subfields (clear and $9)
var subfields = field_start.getElementsByTagName('input');
var re = /^tag_\d*_code_/;
for(var i=0, len = subfields.length ; i< len ; i++) { // browse all subfields
if(subfields[i].hasAttribute('name') == 0 ) {continue; } // div elements specific to Select2
if(subfields[i].getAttribute('name').match(re)){ // it s a subfield
var code = subfields[i]; // code is the first input
var subfield = subfields[i+1]; // subfield the second
[% IF ( clear ) %]
if (subfield){subfield.value="" ;}
[% ELSE %]
if(code.value=='9'){
subfield.value = "[% To.json(authid) | $raw %]";
subfield.className = subfield.className.replace("no_matching_authority_field", "matching_authority_field");
break;
}
[% END %]
}
}
//Delete create authority button and status
var linkinfos = field_start.getElementsByTagName('i');
for (index = linkinfos.length - 1; index >= 0; index--) {
linkinfos[index].parentNode.removeChild(linkinfos[index]);
}
//Change message autolinker_dialog
var subfield_dialog = $(autolinker_dialog).children('ul').children('li');
for (index = subfield_dialog.length - 1; index >= 0; index--){
var tag_field = field_start.id.split("_")[1];
if (subfield_dialog[index].innerHTML.indexOf(tag_field) !== -1 ){
subfield_dialog[index].innerHTML = subfield_dialog[index].innerHTML.replace(_("No matching authority found."), _("No matching authority found. A new authority was created or imported"));
break;
}
}
[% END %]
opener.close();
window.close();
return false;
});
</script>
[% END %]
[% INCLUDE 'intranet-bottom.inc' popup_window = 1 %]