From 88985ffa8da7a5e17f78cc938e12e643b43a740e Mon Sep 17 00:00:00 2001 From: Witold Filipczyk Date: Sat, 18 Dec 2021 09:31:45 +0100 Subject: [PATCH] [quickjs] closest rewritten a bit --- src/ecmascript/quickjs/element.c | 58 ++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/src/ecmascript/quickjs/element.c b/src/ecmascript/quickjs/element.c index 7de87abb9..9a36c5897 100644 --- a/src/ecmascript/quickjs/element.c +++ b/src/ecmascript/quickjs/element.c @@ -1127,6 +1127,19 @@ js_element_cloneNode(JSContext *ctx, JSValueConst this_val, int argc, JSValueCon } } +static bool +isAncestor(xmlpp::Element *el, xmlpp::Element *node) +{ + while (node) { + if (el == node) { + return true; + } + node = node->get_parent(); + } + + return false; +} + static JSValue js_element_closest(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { @@ -1150,26 +1163,31 @@ js_element_closest(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst } xmlpp::ustring css = str; xmlpp::ustring xpath = css2xpath(css); - - if (xpath[0] == '/' && xpath[1] == '/') - { - xpath = xmlpp::ustring("descendant-or-self::") + xpath.substr(2); - } JS_FreeCString(ctx, str); xmlpp::Node::NodeSet elements; - do { - try { - elements = el->find(xpath); - if (elements.size()) { - return getElement(ctx, el); + try { + elements = el->find(xpath); + } catch (xmlpp::exception) { + return JS_NULL; + } + + if (elements.size() == 0) { + return JS_NULL; + } + + while (el) + { + for (auto node: elements) + { + if (isAncestor(el, node)) + { + return getElement(ctx, node); } - el = dynamic_cast(el->get_parent()); - } catch (xmlpp::exception) { - return JS_NULL; } - } while (el); + el = el->get_parent(); + } return JS_NULL; } @@ -1483,18 +1501,6 @@ js_element_matches(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst return JS_NewBool(ctx, elements.size()); } -static bool -isAncestor(xmlpp::Element *el, xmlpp::Element *node) -{ - while (node) { - if (el == node) { - return true; - } - node = node->get_parent(); - } - - return false; -} static JSValue js_element_querySelector(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)