KHtml

wa_selectors.cpp
1 /*
2  * This file is part of the DOM implementation for KDE.
3  *
4  * Copyright (C) 2010 Maksim Orlovich ([email protected])
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB. If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 
22 #include "wa_selectors.h"
23 #include "xml/dom_nodeimpl.h"
24 #include "xml/dom_elementimpl.h"
25 #include "xml/dom_nodelistimpl.h"
26 #include <wtf/RefPtr.h>
27 
28 #include "css/cssparser.h"
29 #include "css/cssstyleselector.h"
30 
31 using namespace DOM;
32 
33 namespace khtml
34 {
35 
36 namespace SelectorQuery
37 {
38 
39 static WTF::PassRefPtr<DOM::NodeListImpl> querySelectorImp(bool justOne, DOM::NodeImpl *root, const DOM::DOMString &query, int &ec)
40 {
41  // Parse the query.
42  CSSParser p;
43  QList<CSSSelector *> selectors = p.parseSelectorList(root->document(), query);
44 
45  if (selectors.isEmpty()) {
46  ec = DOMException::SYNTAX_ERR;
47  return nullptr;
48  }
49 
50  khtml::CSSStyleSelector *styleSelector = root->document()->styleSelector();
51 
52  // ### not in the spec.
53  if (!styleSelector) {
54  ec = DOMException::INVALID_STATE_ERR;
55  return nullptr;
56  }
57 
58  // Check for matches. We specialize some paths for common selectors.
59  DOM::StaticNodeListImpl *matches = new DOM::StaticNodeListImpl;
60 
61  bool requiresClass = true;
62  bool requiresId = true;
63  for (int i = 0; i < selectors.size(); ++i) {
64  if (selectors[i]->match != CSSSelector::Class) {
65  requiresClass = false;
66  }
67  if (selectors[i]->match != CSSSelector::Id) {
68  requiresId = false;
69  }
70  }
71 
72  for (DOM::NodeImpl *cur = root; cur; cur = cur->traverseNextNode(root)) {
73  if (requiresClass && !cur->hasClass()) {
74  continue;
75  }
76 
77  if (requiresId && !cur->hasID()) {
78  continue;
79  }
80 
81  DOM::ElementImpl *e = nullptr;
82  if (cur->isElementNode()) {
83  e = static_cast<DOM::ElementImpl *>(cur);
84  }
85 
86  if (e && styleSelector->isMatchedByAnySelector(e, selectors)) {
87  matches->append(e);
88  if (justOne) {
89  break;
90  }
91  }
92  }
93 
94  // Cleanup the selectors.
95  qDeleteAll(selectors);
96 
97  // all done
98  return matches;
99 }
100 
101 WTF::PassRefPtr<DOM::ElementImpl> querySelector(DOM::NodeImpl *root, const DOM::DOMString &query, int &ec)
102 {
103  WTF::RefPtr<DOM::NodeListImpl> nl = querySelectorImp(true, root, query, ec);
104 
105  if (nl && nl->length()) {
106  return static_cast<DOM::ElementImpl *>(nl->item(0));
107  }
108 
109  return nullptr;
110 }
111 
112 WTF::PassRefPtr<DOM::NodeListImpl> querySelectorAll(DOM::NodeImpl *root, const DOM::DOMString &query, int &ec)
113 {
114  return querySelectorImp(false, root, query, ec);
115 }
116 
117 } // namespace SelectorQuery
118 
119 } // namespace khtml
120 
This file is part of the HTML rendering engine for KDE.
int size() const const
bool isEmpty() const const
This class implements the basic string we use in the DOM.
Definition: dom_string.h:44
the StyleSelector implementation for CSS.
This library provides a full-featured HTML parser and widget.
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Oct 26 2021 22:48:10 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.