From 21f76d834035eb1453828ed9f44ce9ed22b1e3fb Mon Sep 17 00:00:00 2001 From: Andreas Roussos Date: Tue, 21 Feb 2023 20:02:19 +0100 Subject: [PATCH] Bug 29578: Upgrade the jQuery highlighter plugin MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Under certain conditions, the jQuery term highlighter can break and in the process make the "Highlight" / "Unhighlight" button disappear altogether. This affects catalog searches in both the OPAC and the Staff Client, with UNIMARC-based instances affected the most as the "Highlight" / "Unhighlight" button disappears if you perform a specific OPAC search (see Test plan below). This patch fixes that by upgrading the highlighter plugin to its latest version for both the OPAC and the Staff interface. Then, the changes from commit 2e4b574074 (Bug 5844) are applied to the plugin code. Also, Koha uses "term" instead of "highlight" as the class name for the highlighting elements, so the plugin code is modified for that aspect, too. Finally, the plugin file is renamed to reflect the version change (v3 -> v5) and all references to the old filename in the Template files are updated. Test plan: 0) In a UNIMARC instance, catalogue two books using the titles given below (Title subfield = 200$a): Book 1: Συλλογής των εν επιτομή τοῖς πάλαι γεωγραφηθέντων Book 2: Επιτομή της ιστορίας των Βαλκανικών Πολέμων (1912-1913) 1) OpacHighlightedWords and StaffHighlightedWords should both be set to "Highlight". 2) Search the OPAC for "επιτομή των" (without the quotes). In the results page, notice that: a) You get an Uncaught DOMException error in the web browswer's JavaScript Console (press F12): "Failed to execute 'splitText' on 'Text': The offset 3 is larger than the Text node's length." b) the "Highlight" / "Unhighlight" button vanishes c) some search terms matches are not highlighted (for example "των" in the 2nd Book) 3) Repeat the same search in the Staff interface. In the results page, notice that: a) You get an Uncaught DOMException error in the web browswer's JavaScript Console (press F12): "Failed to execute 'splitText' on 'Text': The offset 3 is larger than the Text node's length." b) Even though some terms are highlighted, the button still says "Highlight" c) some search terms matches are not highlighted (for example "των" in the 2nd Book) 4) Apply this patch. 5) Repeat the searches (you may have to press CTRL-F5 to reload the JavaScript code). This time the "Highlight" / "Unhighlight" button is displayed in the OPAC, and all your search terms should be highlighted in yellow. Toggling the highlight should cause no problems, and there shouldn't be any errors logged in your browser's Console. Signed-off-by: Christian Nelson Signed-off-by: Katrin Fischer Signed-off-by: Tomas Cohen Arazi (cherry picked from commit bee56606a6cf6b7f42578ed615d5a333b312d252) Signed-off-by: Fridolin Somers (cherry picked from commit f98e4faee213b2c617ccc040a89542b2f54639c9) Signed-off-by: Matt Blenkinsop --- ...y.highlight-3.js => jquery.highlight-5.js} | 7 +-- .../prog/en/includes/js_includes.inc | 2 +- .../bootstrap/en/modules/opac-detail.tt | 2 +- .../bootstrap/en/modules/opac-results.tt | 2 +- .../lib/jquery/plugins/jquery.highlight-3.js | 8 +-- .../lib/jquery/plugins/jquery.highlight-5.js | 50 +++++++++++++++++++ 6 files changed, 62 insertions(+), 9 deletions(-) rename koha-tmpl/intranet-tmpl/lib/jquery/plugins/{jquery.highlight-3.js => jquery.highlight-5.js} (86%) create mode 100644 koha-tmpl/opac-tmpl/lib/jquery/plugins/jquery.highlight-5.js diff --git a/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.highlight-3.js b/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.highlight-5.js similarity index 86% rename from koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.highlight-3.js rename to koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.highlight-5.js index 8eabca4bfd..578da60639 100644 --- a/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.highlight-3.js +++ b/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.highlight-5.js @@ -1,6 +1,6 @@ /* -highlight v3 +highlight v5 Highlights arbitrary terms. @@ -19,6 +19,7 @@ jQuery.fn.highlight = function(pat) { var skip = 0; if (node.nodeType == 3) { var pos = node.data.toUpperCase().indexOf(pat); + pos -= (node.data.substr(0, pos).toUpperCase().length - node.data.substr(0, pos).length); if (pos >= 0) { var spannode = document.createElement('span'); spannode.className = 'term'; @@ -37,9 +38,9 @@ jQuery.fn.highlight = function(pat) { } return skip; } - return this.each(function() { + return this.length && pat && pat.length ? this.each(function() { innerHighlight(this, pat.toUpperCase()); - }); + }) : this; }; jQuery.fn.removeHighlight = function() { diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/js_includes.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/js_includes.inc index bd41d755a6..b1d131b65d 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/js_includes.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/js_includes.inc @@ -21,7 +21,7 @@ [% Asset.js("lib/jquery/jquery-ui-1.13.1.min.js") | $raw %] [% Asset.js("lib/shortcut/shortcut.js") | $raw %] [% Asset.js("lib/js-cookie/js.cookie-2.2.1.min.js") | $raw %] -[% Asset.js("lib/jquery/plugins/jquery.highlight-3.js") | $raw %] +[% Asset.js("lib/jquery/plugins/jquery.highlight-5.js") | $raw %] [% Asset.js("lib/bootstrap/bootstrap.min.js") | $raw %] [% Asset.js("lib/jquery/plugins/jquery.validate.min.js") | $raw %] diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt index 31f967f010..f918bbbecb 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt @@ -1445,7 +1445,7 @@ [% Asset.js("js/ratings.js") | $raw %] [% END %] - [% IF ( OpacHighlightedWords ) %][% Asset.js("lib/jquery/plugins/jquery.highlight-3.js") | $raw %][% END %] + [% IF ( OpacHighlightedWords ) %][% Asset.js("lib/jquery/plugins/jquery.highlight-5.js") | $raw %][% END %] [% IF ( Koha.Preference('OPACDetailQRCode') ) %] [% Asset.js("lib/kjua/kjua.min.js") | $raw %] [% END %] diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt index 0524b2ff38..062628b7b4 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt +++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt @@ -580,7 +580,7 @@ [% Asset.js("js/authtoresults.js") | $raw %] [% Asset.js("lib/hc-sticky.js") | $raw %] [% IF ( OpacHighlightedWords ) %] - [% Asset.js("lib/jquery/plugins/jquery.highlight-3.js") | $raw %] + [% Asset.js("lib/jquery/plugins/jquery.highlight-5.js") | $raw %] [% END %] [% IF OpenLibraryCovers || OpenLibrarySearch %] [% Asset.js("js/openlibrary.js") | $raw %] diff --git a/koha-tmpl/opac-tmpl/bootstrap/lib/jquery/plugins/jquery.highlight-3.js b/koha-tmpl/opac-tmpl/bootstrap/lib/jquery/plugins/jquery.highlight-3.js index 8eabca4bfd..2e9f39e933 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/lib/jquery/plugins/jquery.highlight-3.js +++ b/koha-tmpl/opac-tmpl/bootstrap/lib/jquery/plugins/jquery.highlight-3.js @@ -1,6 +1,6 @@ /* -highlight v3 +highlight v5 Highlights arbitrary terms. @@ -19,6 +19,7 @@ jQuery.fn.highlight = function(pat) { var skip = 0; if (node.nodeType == 3) { var pos = node.data.toUpperCase().indexOf(pat); + pos -= (node.data.substr(0, pos).toUpperCase().length - node.data.substr(0, pos).length); if (pos >= 0) { var spannode = document.createElement('span'); spannode.className = 'term'; @@ -37,9 +38,9 @@ jQuery.fn.highlight = function(pat) { } return skip; } - return this.each(function() { + return this.length && pat && pat.length ? this.each(function() { innerHighlight(this, pat.toUpperCase()); - }); + }) : this; }; jQuery.fn.removeHighlight = function() { @@ -47,3 +48,4 @@ jQuery.fn.removeHighlight = function() { $(this).contents().unwrap(); }); }; + diff --git a/koha-tmpl/opac-tmpl/lib/jquery/plugins/jquery.highlight-5.js b/koha-tmpl/opac-tmpl/lib/jquery/plugins/jquery.highlight-5.js new file mode 100644 index 0000000000..578da60639 --- /dev/null +++ b/koha-tmpl/opac-tmpl/lib/jquery/plugins/jquery.highlight-5.js @@ -0,0 +1,50 @@ +/* + +highlight v5 + +Highlights arbitrary terms. + + + +MIT license. + +Johann Burkard + + + +*/ + +jQuery.fn.highlight = function(pat) { + function innerHighlight(node, pat) { + var skip = 0; + if (node.nodeType == 3) { + var pos = node.data.toUpperCase().indexOf(pat); + pos -= (node.data.substr(0, pos).toUpperCase().length - node.data.substr(0, pos).length); + if (pos >= 0) { + var spannode = document.createElement('span'); + spannode.className = 'term'; + var middlebit = node.splitText(pos); + var endbit = middlebit.splitText(pat.length); + var middleclone = middlebit.cloneNode(true); + spannode.appendChild(middleclone); + middlebit.parentNode.replaceChild(spannode, middlebit); + skip = 1; + } + } + else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) { + for (var i = 0; i < node.childNodes.length; ++i) { + i += innerHighlight(node.childNodes[i], pat); + } + } + return skip; + } + return this.length && pat && pat.length ? this.each(function() { + innerHighlight(this, pat.toUpperCase()); + }) : this; +}; + +jQuery.fn.removeHighlight = function() { + return this.find("span.term").each(function() { + $(this).contents().unwrap(); + }); +}; -- 2.20.1