GNU bug report logs - #63342
28.2; dom-by-class does not handle nodes with multiple classes properly

Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.

Package: emacs; Reported by: Tim Landscheidt <tim@HIDDEN>; Keywords: patch pending; dated Sun, 7 May 2023 03:36:02 UTC; Maintainer for emacs is bug-gnu-emacs@HIDDEN.
Added tag(s) pending. Request was from Stefan Kangas <stefankangas@HIDDEN> to control <at> debbugs.gnu.org. Full text available.

Message received at submit <at> debbugs.gnu.org:


Received: (at submit) by debbugs.gnu.org; 7 May 2023 03:35:44 +0000
From debbugs-submit-bounces <at> debbugs.gnu.org Sat May 06 23:35:44 2023
Received: from localhost ([127.0.0.1]:36116 helo=debbugs.gnu.org)
	by debbugs.gnu.org with esmtp (Exim 4.84_2)
	(envelope-from <debbugs-submit-bounces <at> debbugs.gnu.org>)
	id 1pvVBX-0002Kq-PE
	for submit <at> debbugs.gnu.org; Sat, 06 May 2023 23:35:44 -0400
Received: from andalucia.tim-landscheidt.de ([116.203.78.250]:53554)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <tim@HIDDEN>) id 1pvVBV-0002Ke-CF
 for submit <at> debbugs.gnu.org; Sat, 06 May 2023 23:35:42 -0400
Received: from [195.226.160.202] (port=39952 helo=vagabond)
 by andalucia.tim-landscheidt.de with esmtpsa
 (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89)
 (envelope-from <tim@HIDDEN>) id 1pvVBU-0001Mw-2R
 for submit <at> debbugs.gnu.org; Sun, 07 May 2023 03:35:40 +0000
From: Tim Landscheidt <tim@HIDDEN>
To: submit <at> debbugs.gnu.org
Subject: 28.2; dom-by-class does not handle nodes with multiple classes
 properly
Organization: https://www.tim-landscheidt.de/
Date: Sun, 07 May 2023 03:35:39 +0000
Message-ID: <875y9495kk.fsf@HIDDEN>
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.2 (gnu/linux)
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-=-="
X-Spam-Score: 0.0 (/)
X-Debbugs-Envelope-To: submit
X-BeenThere: debbugs-submit <at> debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
List-Id: <debbugs-submit.debbugs.gnu.org>
List-Unsubscribe: <https://debbugs.gnu.org/cgi-bin/mailman/options/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=unsubscribe>
List-Archive: <https://debbugs.gnu.org/cgi-bin/mailman/private/debbugs-submit/>
List-Post: <mailto:debbugs-submit <at> debbugs.gnu.org>
List-Help: <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=help>
List-Subscribe: <https://debbugs.gnu.org/cgi-bin/mailman/listinfo/debbugs-submit>, 
 <mailto:debbugs-submit-request <at> debbugs.gnu.org?subject=subscribe>
Errors-To: debbugs-submit-bounces <at> debbugs.gnu.org
Sender: "Debbugs-submit" <debbugs-submit-bounces <at> debbugs.gnu.org>
X-Spam-Score: -1.0 (-)

--=-=-=
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Package: emacs
Version: 28.2
Tags: patch

dom-by-class's docstring says:

| Return elements in DOM that have a class name that matches regexp MATCH.

However, it does not match its argument against the ele-
ments' class names, but their class attributes.  The class
attribute can be composed of multiple, space-separated class
names.

This means that a node:

| <p class=3D"class1 class12">=E2=80=A6

will not get matched by (dom-by-class dom "^class1$").

This can be worked around by using matches =C3=A0 la:

| "\\(?:^\\| \\)class1\\(?:$\\| \\)"

The attached patch fixes this by testing the match for each
class name individually.

--=-=-=
Content-Type: text/x-patch
Content-Disposition: inline; filename=fix-dom-by-class.patch

diff --git a/lisp/dom.el b/lisp/dom.el
index 3066673954a..314a38f194f 100644
--- a/lisp/dom.el
+++ b/lisp/dom.el
@@ -131,7 +131,12 @@ dom-strings
 
 (defun dom-by-class (dom match)
   "Return elements in DOM that have a class name that matches regexp MATCH."
-  (dom-elements dom 'class match))
+  (dom-search dom
+              (lambda (d)
+                (if-let ((class-attr (dom-attr d 'class)))
+                    (seq-find
+                     (apply-partially #'string-match match)
+                     (split-string class-attr " "))))))
 
 (defun dom-by-style (dom match)
   "Return elements in DOM that have a style that matches regexp MATCH."
diff --git a/test/lisp/dom-tests.el b/test/lisp/dom-tests.el
index abb586435a7..213c367b3d8 100644
--- a/test/lisp/dom-tests.el
+++ b/test/lisp/dom-tests.el
@@ -43,7 +43,16 @@ dom-tests--tree
                       (dom-node "div" '((class . "foo")
                                         (style . "color: red;"))
                                 (dom-node "p" '((id . "bar"))
-                                          "foo"))
+                                          "foo")
+                                (dom-node "p" '((id . "test-case-1")
+                                                (class . "class1"))
+                                          "text1")
+                                (dom-node "p" '((id . "test-case-2")
+                                                (class . "class12"))
+                                          "text2")
+                                (dom-node "p" '((id . "test-case-3")
+                                                (class . "class1 class2"))
+                                          "text3"))
                       (dom-node "div" '((title . "2nd div"))
                                 "bar"))))
 
@@ -105,8 +114,9 @@ dom-tests--tree
 
 (ert-deftest dom-tests-texts ()
   (let ((dom (dom-tests--tree)))
-    (should (equal (dom-texts dom) "Test foo bar"))
-    (should (equal (dom-texts dom ", ") "Test, foo, bar"))))
+    (should (equal (dom-texts dom) "Test foo text1 text2 text3 bar"))
+    (should (equal (dom-texts dom ", ")
+                   "Test, foo, text1, text2, text3, bar"))))
 
 (ert-deftest dom-tests-child-by-tag ()
   (let ((dom (dom-tests--tree)))
@@ -121,13 +131,29 @@ dom-tests--tree
 
 (ert-deftest dom-tests-strings ()
   (let ((dom (dom-tests--tree)))
-    (should (equal (dom-strings dom) '("Test" "foo" "bar")))
+    (should (equal (dom-strings dom)
+                   '("Test" "foo" "text1" "text2" "text3" "bar")))
     (should (equal (dom-strings (dom-children dom)) '("Test")))))
 
 (ert-deftest dom-tests-by-class ()
   (let ((dom (dom-tests--tree)))
     (should (equal (dom-tag (dom-by-class dom "foo")) "div"))
-    (should-not (dom-by-class dom "bar"))))
+    (should-not (dom-by-class dom "bar"))
+    (should (equal (mapcar (lambda (d) (dom-attr d 'id))
+                           (dom-by-class dom "class1"))
+                   '("test-case-1" "test-case-2" "test-case-3")))
+    (should (equal (mapcar (lambda (d) (dom-attr d 'id))
+                           (dom-by-class dom "class1$"))
+                   '("test-case-1" "test-case-3")))
+    (should (equal (mapcar (lambda (d) (dom-attr d 'id))
+                           (dom-by-class dom "^class2"))
+                   '("test-case-3")))
+    ;; Test that workaround still works.
+    (should (equal (mapcar (lambda (d) (dom-attr d 'id))
+                           (dom-by-class
+                            dom
+                            "\\(?:^\\| \\)class1\\(?:$\\| \\)"))
+                   '("test-case-1" "test-case-3")))))
 
 (ert-deftest dom-tests-by-style ()
   (let ((dom (dom-tests--tree)))

--=-=-=--




Acknowledgement sent to Tim Landscheidt <tim@HIDDEN>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs@HIDDEN. Full text available.
Report forwarded to bug-gnu-emacs@HIDDEN:
bug#63342; Package emacs. Full text available.
Please note: This is a static page, with minimal formatting, updated once a day.
Click here to see this page with the latest information and nicer formatting.
Last modified: Wed, 6 Sep 2023 20:45:02 UTC

GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997 nCipher Corporation Ltd, 1994-97 Ian Jackson.