KHtml

kjs_xpath.cpp
1 /*
2  * This file is part of the KDE libraries
3  * Copyright (C) 2010 Maksim Orlovich <[email protected]>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 #include "kjs_xpath.h"
20 #include "kjs_dom.h"
21 
22 #include "dom/dom3_xpath.h"
23 
24 using KJS::XPathResult;
25 
26 #include "kjs_xpath.lut.h"
27 
28 namespace KJS
29 {
30 
31 // -------------------------------------------------------------------------
32 /*
33 @begin XPathResultConstantsTable 13
34  ANY_TYPE DOM::XPath::ANY_TYPE DontDelete|ReadOnly
35  NUMBER_TYPE DOM::XPath::NUMBER_TYPE DontDelete|ReadOnly
36  STRING_TYPE DOM::XPath::STRING_TYPE DontDelete|ReadOnly
37  BOOLEAN_TYPE DOM::XPath::BOOLEAN_TYPE DontDelete|ReadOnly
38  UNORDERED_NODE_ITERATOR_TYPE DOM::XPath::UNORDERED_NODE_ITERATOR_TYPE DontDelete|ReadOnly
39  ORDERED_NODE_ITERATOR_TYPE DOM::XPath::ORDERED_NODE_ITERATOR_TYPE DontDelete|ReadOnly
40  UNORDERED_NODE_SNAPSHOT_TYPE DOM::XPath::UNORDERED_NODE_SNAPSHOT_TYPE DontDelete|ReadOnly
41  ORDERED_NODE_SNAPSHOT_TYPE DOM::XPath::ORDERED_NODE_SNAPSHOT_TYPE DontDelete|ReadOnly
42  ANY_UNORDERED_NODE_TYPE DOM::XPath::ANY_UNORDERED_NODE_TYPE DontDelete|ReadOnly
43  FIRST_ORDERED_NODE_TYPE DOM::XPath::FIRST_ORDERED_NODE_TYPE DontDelete|ReadOnly
44 @end
45 */
46 DEFINE_CONSTANT_TABLE(XPathResultConstants)
47 IMPLEMENT_CONSTANT_TABLE(XPathResultConstants, "XPathResultConstants")
48 // -------------------------------------------------------------------------
49 /*
50 @begin XPathResultProtoTable 3
51  iterateNext XPathResult::IterateNext DontDelete|Function 0
52  snapshotItem XPathResult::SnapshotItem DontDelete|Function 1
53 @end
54 */
55 KJS_DEFINE_PROTOTYPE(XPathResultProto)
56 KJS_IMPLEMENT_PROTOFUNC(XPathResultProtoFunc)
57 KJS_IMPLEMENT_PROTOTYPE("XPathResult", XPathResultProto, XPathResultProtoFunc, XPathResultConstants)
58 IMPLEMENT_PSEUDO_CONSTRUCTOR_WITH_PARENT(XPathResultPseudoCtor, "XPathResult", XPathResultProto, XPathResultConstants)
59 
60 /*
61 @begin XPathResultTable 11
62  resultType XPathResult::ResultType DontDelete|ReadOnly
63  numberValue XPathResult::NumberValue DontDelete|ReadOnly
64  stringValue XPathResult::StringValue DontDelete|ReadOnly
65  booleanValue XPathResult::BooleanValue DontDelete|ReadOnly
66  singleNodeValue XPathResult::SingleNodeValue DontDelete|ReadOnly
67  invalidIteratorState XPathResult::InvalidIteratorState DontDelete|ReadOnly
68  snapshotLength XPathResult::SnapshotLength DontDelete|ReadOnly
69 @end
70 */
71 const ClassInfo XPathResult::info = { "XPathResult", nullptr, &XPathResultTable, nullptr };
72 
73 XPathResult::XPathResult(ExecState *exec, khtml::XPathResultImpl *impl):
74  WrapperBase(XPathResultProto::self(exec), impl)
75 {}
76 
77 JSValue *XPathResultProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
78 {
79  KJS_CHECK_THIS(XPathResult, thisObj);
80 
81  khtml::XPathResultImpl *imp = static_cast<XPathResult *>(thisObj)->impl();
82  DOMExceptionTranslator exception(exec);
83 
84  switch (id) {
85  case XPathResult::IterateNext:
86  return getDOMNode(exec, imp->iterateNext(exception));
87  case XPathResult::SnapshotItem:
88  return getDOMNode(exec, imp->snapshotItem(args[0]->toInt32(exec), exception));
89  }
90 
91  return jsUndefined();
92 }
93 
94 bool XPathResult::getOwnPropertySlot(ExecState *exec, const Identifier &p, PropertySlot &slot)
95 {
96  return getStaticValueSlot<XPathResult, DOMObject>(exec, &XPathResultTable,
97  this, p, slot);
98 }
99 
100 JSValue *XPathResult::getValueProperty(ExecState *exec, int token) const
101 {
102  DOMExceptionTranslator exception(exec);
103  switch (token) {
104  case ResultType:
105  return jsNumber(impl()->resultType());
106  case NumberValue:
107  return jsNumber(impl()->numberValue(exception));
108  case StringValue:
109  return jsString(impl()->stringValue(exception));
110  case BooleanValue:
111  return jsBoolean(impl()->booleanValue(exception));
112  case SingleNodeValue:
113  return getDOMNode(exec, impl()->singleNodeValue(exception));
114  case InvalidIteratorState:
115  return jsBoolean(impl()->invalidIteratorState());
116  case SnapshotLength:
117  return jsNumber(impl()->snapshotLength(exception));
118  default:
119  assert(0);
120  return jsUndefined();
121  }
122 }
123 
124 // -------------------------------------------------------------------------
125 /*
126 @begin XPathExpressionProtoTable 3
127  evaluate XPathExpression::Evaluate DontDelete|Function 2
128 @end
129 */
130 KJS_DEFINE_PROTOTYPE(XPathExpressionProto)
131 KJS_IMPLEMENT_PROTOFUNC(XPathExpressionProtoFunc)
132 KJS_IMPLEMENT_PROTOTYPE("XPathExpression", XPathExpressionProto, XPathExpressionProtoFunc, ObjectPrototype)
133 IMPLEMENT_PSEUDO_CONSTRUCTOR(XPathExpressionPseudoCtor, "XPathExpression", XPathExpressionProto)
134 
135 const ClassInfo XPathExpression::info = { "XPathExpression", nullptr, nullptr, nullptr };
136 
137 XPathExpression::XPathExpression(ExecState *exec, khtml::XPathExpressionImpl *impl):
138  WrapperBase(XPathExpressionProto::self(exec), impl), jsResolver(nullptr)
139 {}
140 
141 void XPathExpression::mark()
142 {
143  DOMObject::mark();
144 
145  if (jsResolver && !jsResolver->marked()) {
146  jsResolver->mark();
147  }
148 }
149 
150 JSValue *XPathExpressionProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
151 {
152  KJS_CHECK_THIS(XPathExpression, thisObj);
153 
154  khtml::XPathExpressionImpl *imp = static_cast<XPathExpression *>(thisObj)->impl();
155  DOMExceptionTranslator exception(exec);
156 
157  switch (id) {
158  case XPathExpression::Evaluate:
159  return getWrapper<XPathResult>(exec, imp->evaluate(toNode(args[0]),
160  args[1]->toInt32(exec),
161  nullptr,
162  exception));
163  }
164 
165  return jsUndefined();
166 }
167 
168 // -------------------------------------------------------------------------
169 /*
170 @begin XPathNSResolverProtoTable 3
171  lookupNamespaceURI XPathNSResolver::LookupNamespaceURI DontDelete|Function 1
172 @end
173 */
174 KJS_DEFINE_PROTOTYPE(XPathNSResolverProto)
175 KJS_IMPLEMENT_PROTOFUNC(XPathNSResolverProtoFunc)
176 KJS_IMPLEMENT_PROTOTYPE("XPathNSResolver", XPathNSResolverProto, XPathNSResolverProtoFunc, ObjectPrototype)
177 IMPLEMENT_PSEUDO_CONSTRUCTOR(XPathNSResolverPseudoCtor, "XPathNSResolver", XPathNSResolverProto)
178 
179 const ClassInfo XPathNSResolver::info = { "XPathNSResolver", nullptr, nullptr, nullptr };
180 
181 XPathNSResolver::XPathNSResolver(ExecState *exec, khtml::XPathNSResolverImpl *impl):
182  WrapperBase(XPathNSResolverProto::self(exec), impl)
183 {}
184 
185 JSValue *XPathNSResolverProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args)
186 {
187  KJS_CHECK_THIS(XPathNSResolver, thisObj);
188 
189  khtml::XPathNSResolverImpl *imp = static_cast<XPathNSResolver *>(thisObj)->impl();
190  DOMExceptionTranslator exception(exec);
191 
192  switch (id) {
193  case XPathNSResolver::LookupNamespaceURI:
194  return jsString(imp->lookupNamespaceURI(args[0]->toString(exec).qstring()));
195  }
196 
197  return jsUndefined();
198 }
199 
200 // -------------------------------------------------------------------------
201 
202 JSXPathNSResolver::JSXPathNSResolver(Interpreter *ctx, JSObject *impl): impl(impl), ctx(ctx)
203 {}
204 
205 khtml::XPathNSResolverImpl::Type JSXPathNSResolver::type()
206 {
207  return XPathNSResolverImpl::JS;
208 }
209 
210 DOM::DOMString JSXPathNSResolver::lookupNamespaceURI(const DOM::DOMString &prefix)
211 {
212  // ### this is "heavily inspired" by JSNodeFilter::acceptNode ---
213  // gotta be a way of reducing the dupe. This one doesn't
214  // propagate exceptions, however --- should it?
215  ExecState *exec = ctx->globalExec();
216 
217  JSObject *function = nullptr;
218  if (impl->implementsCall()) {
219  function = impl;
220  } else {
221  // See if we have an object with a lookupNamespaceURI method.
222  JSObject *cand = impl->get(exec, "lookupNamespaceURI")->getObject();
223  if (cand && cand->implementsCall()) {
224  function = cand;
225  }
226  }
227 
228  if (function) {
229  List args;
230  args.append(jsString(prefix));
231 
232  JSValue *result = function->call(exec, impl, args);
233  if (!exec->hadException()) {
234  if (result->isUndefinedOrNull()) {
235  return DOMString();
236  } else {
237  return result->toString(exec).domString();
238  }
239  } else {
240  exec->clearException();
241  }
242  }
243 
244  return DOM::DOMString();
245 }
246 
247 // Convert JS -> DOM. Might make a new JSXPathNSResolver. It does not
248 // protect the JS resolver from collection in any way.
249 khtml::XPathNSResolverImpl *toResolver(ExecState *exec, JSValue *impl)
250 {
251  JSObject *o = impl->getObject();
252  if (!o) {
253  return nullptr;
254  }
255 
256  // Wrapped native object -> unwrap
257  if (o->inherits(&XPathNSResolver::info)) {
258  return static_cast<XPathNSResolver *>(o)->impl();
259  }
260 
261  // A JS object -> wrap it.
262  return new JSXPathNSResolver(exec->dynamicInterpreter(), o);
263 }
264 
265 } // namespace KJS
266 
This class implements the basic string we use in the DOM.
Definition: dom_string.h:44
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Oct 16 2021 22:47:58 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.