| 1034 | } |
| 1035 | |
| 1036 | int Element::GetLocation(LocationInfo* location, |
| 1037 | std::vector<LocationInfo>* frame_locations) { |
| 1038 | LOG(TRACE) << "Entering Element::GetLocation"; |
| 1039 | |
| 1040 | bool has_absolute_position_ready_to_return = false; |
| 1041 | |
| 1042 | CComPtr<IHTMLElement2> element2; |
| 1043 | HRESULT hr = this->element_->QueryInterface(&element2); |
| 1044 | if (FAILED(hr)) { |
| 1045 | LOGHR(WARN, hr) << "Unable to cast element to IHTMLElement2"; |
| 1046 | return EOBSOLETEELEMENT; |
| 1047 | } |
| 1048 | |
| 1049 | long top = 0, bottom = 0, left = 0, right = 0; |
| 1050 | LocationInfo map_location = { 0, 0, 0, 0 }; |
| 1051 | if (this->IsImageMap(&map_location)) { |
| 1052 | left = map_location.x; |
| 1053 | top = map_location.y; |
| 1054 | right = map_location.x + map_location.width; |
| 1055 | bottom = map_location.y + map_location.height; |
| 1056 | } else { |
| 1057 | // If this element is inline, we need to check whether we should |
| 1058 | // use getBoundingClientRect() or the first non-zero-sized rect returned |
| 1059 | // by getClientRects(). If the element is not inline, we can use |
| 1060 | // getBoundingClientRect() directly. |
| 1061 | CComPtr<IHTMLRect> rect; |
| 1062 | if (this->IsInline()) { |
| 1063 | CComPtr<IHTMLRectCollection> rects; |
| 1064 | hr = element2->getClientRects(&rects); |
| 1065 | long rect_count; |
| 1066 | rects->get_length(&rect_count); |
| 1067 | if (rect_count > 1) { |
| 1068 | LOG(DEBUG) << "Element is inline with multiple client rects, finding first non-zero sized client rect"; |
| 1069 | for (long i = 0; i < rect_count; ++i) { |
| 1070 | CComVariant index(i); |
| 1071 | CComVariant rect_variant; |
| 1072 | hr = rects->item(&index, &rect_variant); |
| 1073 | if (SUCCEEDED(hr) && rect_variant.pdispVal) { |
| 1074 | CComPtr<IHTMLRect> qi_rect; |
| 1075 | rect_variant.pdispVal->QueryInterface<IHTMLRect>(&qi_rect); |
| 1076 | if (qi_rect) { |
| 1077 | rect = qi_rect; |
| 1078 | if (RectHasNonZeroDimensions(rect)) { |
| 1079 | // IE returns absolute positions in the page, rather than frame- and scroll-bound |
| 1080 | // positions, for clientRects (as opposed to boundingClientRects). |
| 1081 | has_absolute_position_ready_to_return = true; |
| 1082 | break; |
| 1083 | } |
| 1084 | } |
| 1085 | } |
| 1086 | } |
| 1087 | } |
| 1088 | else { |
| 1089 | LOG(DEBUG) << "Element is inline with one client rect, using IHTMLElement2::getBoundingClientRect"; |
| 1090 | hr = element2->getBoundingClientRect(&rect); |
| 1091 | } |
| 1092 | } |
| 1093 | else { |
no test coverage detected