From 382b2702a069fec82801bc2297f8c524c5f53a5b Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Tue, 26 Jul 2022 13:55:20 +0200 Subject: [PATCH] utils.js: Optimize performance of `getCSSPath()` --- public/js/icinga/utils.js | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/public/js/icinga/utils.js b/public/js/icinga/utils.js index 76184d2a4e..280e4f6416 100644 --- a/public/js/icinga/utils.js +++ b/public/js/icinga/utils.js @@ -371,15 +371,19 @@ var path = []; while (true) { - var id = element.getAttribute("id"); - - // Only use ids if they're truly unique - // TODO: The check used to use document.querySelectorAll, but this resulted in many issues with ids - // that start with a decimal. jQuery seems to escape those correctly, so this is the only reason - // why it's still.. jQuery. - if (!! id && $('* #' + id).length === 1) { - path.push('#' + id); - break; + let id = element.id; + if (typeof id !== 'undefined' && typeof id !== 'string') { + // Sometimes there may be a form element with the name "id" + id = element.getAttribute("id"); + } + + if (!! id) { + // Only use ids if they're truly unique + let results = document.querySelectorAll('* #' + this.escapeCSSSelector(id)); + if (results.length === 1) { + path.push('#' + id); + break; + } } var tagName = element.tagName; @@ -409,6 +413,20 @@ return path.reverse().join(' > '); }, + /** + * Escape the given string to be used in a CSS selector + * + * @param {string} selector + * @returns {string} + */ + escapeCSSSelector: function (selector) { + if (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') { + return CSS.escape(selector); + } + + return selector.replaceAll(/^(\d)/, '\\\\3$1 '); + }, + /** * Climbs up the given dom path and returns the element *