From 5eaecbb00e2c2f8cac88499667d4e5118014b02a 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()` (cherry picked from commit 22cb1f2143a7249f3f0c022448337f0625cd58d1) --- public/js/icinga/utils.js | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/public/js/icinga/utils.js b/public/js/icinga/utils.js index 76184d2a4..280e4f641 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"); + 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"); + } - // 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; + 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 *