| 1411 | } |
| 1412 | |
| 1413 | bool Element::GetClickableViewPortLocation(const bool document_contains_frames, LocationInfo* location) { |
| 1414 | LOG(TRACE) << "Entering Element::GetClickableViewPortLocation"; |
| 1415 | |
| 1416 | WINDOWINFO window_info; |
| 1417 | window_info.cbSize = sizeof(WINDOWINFO); |
| 1418 | BOOL get_window_info_result = ::GetWindowInfo(this->containing_window_handle_, &window_info); |
| 1419 | if (get_window_info_result == FALSE) { |
| 1420 | LOGERR(WARN) << "Cannot determine size of window, call to GetWindowInfo API failed"; |
| 1421 | return false; |
| 1422 | } |
| 1423 | |
| 1424 | long window_width = window_info.rcClient.right - window_info.rcClient.left; |
| 1425 | long window_height = window_info.rcClient.bottom - window_info.rcClient.top; |
| 1426 | |
| 1427 | // If we're not on the top-level document, we can assume that the view port |
| 1428 | // includes the entire client window, since scrollIntoView should do the |
| 1429 | // right thing and make it visible. Otherwise, we prefer getting the view |
| 1430 | // port size by either getting the window.innerWidth and .innerHeight, or |
| 1431 | // by using documentElement.clientHeight and .clientWidth. |
| 1432 | if (!document_contains_frames) { |
| 1433 | CComPtr<IHTMLDocument2> doc; |
| 1434 | int status_code = this->GetContainingDocument(false, &doc); |
| 1435 | if (status_code == WD_SUCCESS) { |
| 1436 | bool used_window_properties = false; |
| 1437 | CComPtr<IHTMLWindow2> parent_window; |
| 1438 | HRESULT hr = doc->get_parentWindow(&parent_window); |
| 1439 | if (SUCCEEDED(hr) && parent_window) { |
| 1440 | CComPtr<IHTMLWindow7> window; |
| 1441 | hr = parent_window->QueryInterface<IHTMLWindow7>(&window); |
| 1442 | if (SUCCEEDED(hr) && window) { |
| 1443 | window->get_innerHeight(&window_height); |
| 1444 | window->get_innerWidth(&window_width); |
| 1445 | used_window_properties = true; |
| 1446 | } |
| 1447 | } |
| 1448 | |
| 1449 | // If using the window object's innerWidth and innerHeight properties |
| 1450 | // failed, then fall back to the document element's clientWidth and |
| 1451 | // clientHeight properties. |
| 1452 | if (!used_window_properties) { |
| 1453 | int document_mode = DocumentHost::GetDocumentMode(doc); |
| 1454 | CComPtr<IHTMLDocument3> document_element_doc; |
| 1455 | CComPtr<IHTMLElement> document_element; |
| 1456 | hr = doc->QueryInterface<IHTMLDocument3>(&document_element_doc); |
| 1457 | if (SUCCEEDED(hr) && document_element_doc) { |
| 1458 | hr = document_element_doc->get_documentElement(&document_element); |
| 1459 | } |
| 1460 | if (SUCCEEDED(hr) && document_mode > 5 && document_element) { |
| 1461 | CComPtr<IHTMLElement2> size_element; |
| 1462 | hr = document_element->QueryInterface<IHTMLElement2>(&size_element); |
| 1463 | size_element->get_clientHeight(&window_height); |
| 1464 | size_element->get_clientWidth(&window_width); |
| 1465 | } else { |
| 1466 | // This branch is only included if getting documentElement fails. |
| 1467 | LOG(WARN) << "Document containing element does not contains frames, " |
| 1468 | << "but getting the documentElement property failed, or the " |
| 1469 | << "doctype has thrown the browser into pre-IE6 rendering. " |
| 1470 | << "The view port calculation may be inaccurate"; |
no test coverage detected