| 241 | } |
| 242 | |
| 243 | int ElementFinder::FindElementsUsingSizzle(const IECommandExecutor& executor, |
| 244 | const ElementHandle parent_wrapper, |
| 245 | const std::wstring& criteria, |
| 246 | Json::Value* found_elements) { |
| 247 | LOG(TRACE) << "Entering ElementFinder::FindElementsUsingSizzle"; |
| 248 | |
| 249 | int result; |
| 250 | |
| 251 | if (criteria == L"") { |
| 252 | // Apparently, Sizzle will happily return an empty array for an empty |
| 253 | // string as the selector. We do not want this. |
| 254 | return ENOSUCHELEMENT; |
| 255 | } |
| 256 | |
| 257 | BrowserHandle browser; |
| 258 | result = executor.GetCurrentBrowser(&browser); |
| 259 | if (result != WD_SUCCESS) { |
| 260 | LOG(WARN) << "Unable to get browser"; |
| 261 | return result; |
| 262 | } |
| 263 | |
| 264 | std::wstring script_source(L"(function() { return function(){ if (!window.Sizzle) {"); |
| 265 | script_source += atoms::asString(atoms::SIZZLE); |
| 266 | script_source += L"}\n"; |
| 267 | script_source += L"var root = arguments[1] ? arguments[1] : document.documentElement;"; |
| 268 | script_source += L"if (root['querySelectorAll']) { return root.querySelectorAll(arguments[0]); } "; |
| 269 | script_source += L"var results = []; try { Sizzle(arguments[0], root, results); } catch(ex) { results = null; }"; |
| 270 | script_source += L"return results;"; |
| 271 | script_source += L"};})();"; |
| 272 | |
| 273 | CComPtr<IHTMLDocument2> doc; |
| 274 | browser->GetDocument(&doc); |
| 275 | |
| 276 | Script script_wrapper(doc, script_source, 2); |
| 277 | script_wrapper.AddArgument(criteria); |
| 278 | if (parent_wrapper) { |
| 279 | // Use a copy for the parent element? |
| 280 | CComPtr<IHTMLElement> parent(parent_wrapper->element()); |
| 281 | script_wrapper.AddArgument(parent); |
| 282 | } |
| 283 | |
| 284 | result = script_wrapper.Execute(); |
| 285 | if (result == WD_SUCCESS) { |
| 286 | CComVariant snapshot = script_wrapper.result(); |
| 287 | if (snapshot.vt == VT_NULL || snapshot.vt == VT_EMPTY) { |
| 288 | // We explicitly caught an error from Sizzle. Return ENOSUCHELEMENT. |
| 289 | return ENOSUCHELEMENT; |
| 290 | } |
| 291 | std::wstring get_element_count_script = L"(function(){return function() {return arguments[0].length;}})();"; |
| 292 | Script get_element_count_script_wrapper(doc, get_element_count_script, 1); |
| 293 | get_element_count_script_wrapper.AddArgument(snapshot); |
| 294 | result = get_element_count_script_wrapper.Execute(); |
| 295 | if (result == WD_SUCCESS) { |
| 296 | *found_elements = Json::Value(Json::arrayValue); |
| 297 | if (!get_element_count_script_wrapper.ResultIsInteger()) { |
| 298 | LOG(WARN) << "Found elements count is not integer"; |
| 299 | result = EUNEXPECTEDJSERROR; |
| 300 | } else { |
no test coverage detected