already_AddRefed<nsIDOMElement> nsXFormsSwitchElement::FindFirstSelectedCase(nsIDOMElement* aDeselected) { nsCOMPtr<nsIDOMNode> child; mElement->GetFirstChild(getter_AddRefs(child)); nsCOMPtr<nsIDOMElement> firstCase; while (child) { nsCOMPtr<nsIDOMElement> childElement(do_QueryInterface(child)); if (childElement && childElement != aDeselected) { if (nsXFormsUtils::IsXFormsElement(child, NS_LITERAL_STRING("case"))) { if (!firstCase) firstCase = childElement; nsCOMPtr<nsIXFormsCaseElement> caseElem(do_QueryInterface(child)); if (caseElem) { PRBool selected; caseElem->GetInitialSelectedState(&selected); if (selected) { firstCase = childElement; break; } } } } nsCOMPtr<nsIDOMNode> tmp; child->GetNextSibling(getter_AddRefs(tmp)); child.swap(tmp); } nsIDOMElement* result; NS_IF_ADDREF(result = firstCase); return result; }
VOID CXElement::On_CXMsg_Layout( CXMsg_Layout& arg ) { URP(arg); if (m_isLayouting) { return; } BOOL layoutinvalid; GetLayoutInvalid(layoutinvalid); if (layoutinvalid) { std::list<ElementRef> needExpandElements; for (auto& i:m_children) { ElementRef childElement(i); BOOL expandWidth; childElement->GetExpandWidth(expandWidth); BOOL expandHeight; childElement->GetExpandHeight(expandHeight); if (expandWidth || expandHeight) { needExpandElements.push_back(childElement); } else { childElement->ProcessXMessage(arg); } } m_isLayouting = TRUE; Layouter::LayouterRef layouter; Property::ELayoutType type = Property::LayoutTypeDefaultValue; GetLayoutType(type); Layouter::GetLayouter(type,layouter); if (layouter) { layouter->Layout(this); } else { WTF; } m_isLayouting = FALSE; SetLayoutInvalid(FALSE); for (auto i:needExpandElements) { i->ProcessXMessage(arg); } } }
int Element::GetLocation(LocationInfo* location, std::vector<LocationInfo>* frame_locations) { LOG(TRACE) << "Entering Element::GetLocation"; bool hasAbsolutePositionReadyToReturn = false; CComPtr<IHTMLElement2> element2; HRESULT hr = this->element_->QueryInterface(&element2); if (FAILED(hr)) { LOGHR(WARN, hr) << "Unable to cast element to IHTMLElement2"; return EOBSOLETEELEMENT; } // If this element is inline, we need to check whether we should // use getBoundingClientRect() or the first non-zero-sized rect returned // by getClientRects(). If the element is not inline, we can use // getBoundingClientRect() directly. CComPtr<IHTMLRect> rect; if (this->IsInline()) { CComPtr<IHTMLRectCollection> rects; hr = element2->getClientRects(&rects); long rect_count; rects->get_length(&rect_count); if (rect_count > 1) { LOG(DEBUG) << "Element is inline with multiple client rects, finding first non-zero sized client rect"; for (long i = 0; i < rect_count; ++i) { CComVariant index(i); CComVariant rect_variant; hr = rects->item(&index, &rect_variant); if (SUCCEEDED(hr) && rect_variant.pdispVal) { CComPtr<IHTMLRect> qi_rect; rect_variant.pdispVal->QueryInterface<IHTMLRect>(&qi_rect); if (qi_rect) { rect = qi_rect; if (RectHasNonZeroDimensions(rect)) { // IE returns absolute positions in the page, rather than frame- and scroll-bound // positions, for clientRects (as opposed to boundingClientRects). hasAbsolutePositionReadyToReturn = true; break; } } } } } else { LOG(DEBUG) << "Element is inline with one client rect, using IHTMLElement2::getBoundingClientRect"; hr = element2->getBoundingClientRect(&rect); } } else { LOG(DEBUG) << "Element is a block element, using IHTMLElement2::getBoundingClientRect"; hr = element2->getBoundingClientRect(&rect); if (this->HasOnlySingleTextNodeChild()) { LOG(DEBUG) << "Element has only a single child text node, using text node boundaries"; // Note that since subsequent statements in this method use the HTMLRect // object, we will update that object with the values of the text node. LocationInfo text_node_location; this->GetTextBoundaries(&text_node_location); rect->put_left(text_node_location.x); rect->put_top(text_node_location.y); rect->put_right(text_node_location.x + text_node_location.width); rect->put_bottom(text_node_location.y + text_node_location.height); } } if (FAILED(hr)) { LOGHR(WARN, hr) << "Cannot figure out where the element is on screen, client rect retrieval failed"; return EUNHANDLEDERROR; } // If the rect of the element has zero width and height, check its // children to see if any of them have width and height, in which // case, this element will be visible. if (!RectHasNonZeroDimensions(rect)) { LOG(DEBUG) << "Element has client rect with zero dimension, checking children for non-zero dimension client rects"; CComPtr<IHTMLDOMNode> node; element2->QueryInterface(&node); CComPtr<IDispatch> children_dispatch; node->get_childNodes(&children_dispatch); CComPtr<IHTMLDOMChildrenCollection> children; children_dispatch->QueryInterface<IHTMLDOMChildrenCollection>(&children); if (!!children) { long childrenCount = 0; children->get_length(&childrenCount); for (long i = 0; i < childrenCount; ++i) { CComPtr<IDispatch> childDispatch; children->item(i, &childDispatch); CComPtr<IHTMLElement> child; childDispatch->QueryInterface(&child); if (child != NULL) { Element childElement(child, this->containing_window_handle_); std::vector<LocationInfo> child_frame_locations; int result = childElement.GetLocation(location, &child_frame_locations); if (result == WD_SUCCESS) { return result; } } } } } long top = 0, bottom = 0, left = 0, right = 0; rect->get_top(&top); rect->get_left(&left); rect->get_bottom(&bottom); rect->get_right(&right); long w = right - left; long h = bottom - top; if (!hasAbsolutePositionReadyToReturn) { // On versions of IE prior to 8 on Vista, if the element is out of the // viewport this would seem to return 0,0,0,0. IE 8 returns position in // the DOM regardless of whether it's in the browser viewport. long scroll_left, scroll_top = 0; element2->get_scrollLeft(&scroll_left); element2->get_scrollTop(&scroll_top); left += scroll_left; top += scroll_top; // Only add the frame offset if the element is actually in a frame. LocationInfo frame_location = {}; bool element_is_in_frame = this->GetFrameDetails(&frame_location, frame_locations); if (element_is_in_frame) { left += frame_location.x; top += frame_location.y; frame_locations->push_back(frame_location); } else { LOG(DEBUG) << "Element is not in a frame"; } } location->x = left; location->y = top; location->width = w; location->height = h; return WD_SUCCESS; }
int Element::GetLocation(long* x, long* y, long* width, long* height) { LOG(TRACE) << "Entering Element::GetLocation"; *x = 0, *y = 0, *width = 0, *height = 0; bool hasAbsolutePositionReadyToReturn = false; CComPtr<IHTMLElement2> element2; HRESULT hr = this->element_->QueryInterface(&element2); if (FAILED(hr)) { LOGHR(WARN, hr) << "Unable to cast element to IHTMLElement2"; return EOBSOLETEELEMENT; } CComPtr<IHTMLRect> rect; if (this->IsInline()) { CComPtr<IHTMLRectCollection> rects; hr = element2->getClientRects(&rects); long rect_count; rects->get_length(&rect_count); if (rect_count > 1) { LOG(DEBUG) << "Element is inline with multiple client rects, finding first non-zero sized client rect"; for (long i = 0; i < rect_count; ++i) { CComVariant index(i); CComVariant rect_variant; hr = rects->item(&index, &rect_variant); if (SUCCEEDED(hr) && rect_variant.pdispVal) { hr = rect_variant.pdispVal->QueryInterface(&rect); if (SUCCEEDED(hr) && RectHasNonZeroDimensions(rect)) { // IE returns absolute positions in the page, rather than frame- and scroll-bound // positions, for clientRects (as opposed to boundingClientRects). hasAbsolutePositionReadyToReturn = true; break; } } } } else { LOG(DEBUG) << "Element is inline with one client rect, using IHTMLElement2::getBoundingClientRect"; hr = element2->getBoundingClientRect(&rect); } } else { LOG(DEBUG) << "Element is a block element, using IHTMLElement2::getBoundingClientRect"; hr = element2->getBoundingClientRect(&rect); } if (FAILED(hr)) { LOGHR(WARN, hr) << "Cannot figure out where the element is on screen, client rect retrieval failed"; return EUNHANDLEDERROR; } // If the rect of the element has zero width and height, check its // children to see if any of them have width and height, in which // case, this element will be visible. if (!RectHasNonZeroDimensions(rect)) { LOG(DEBUG) << "Element has client rect with zero dimension, checking children for non-zero dimension client rects"; CComPtr<IHTMLDOMNode> node; element2->QueryInterface(&node); CComPtr<IDispatch> childrenDispatch; node->get_childNodes(&childrenDispatch); CComQIPtr<IHTMLDOMChildrenCollection> children = childrenDispatch; if (!!children) { long childrenCount = 0; children->get_length(&childrenCount); for (long i = 0; i < childrenCount; ++i) { CComPtr<IDispatch> childDispatch; children->item(i, &childDispatch); CComPtr<IHTMLElement> child; childDispatch->QueryInterface(&child); if (child != NULL) { Element childElement(child, this->containing_window_handle_); int result = childElement.GetLocation(x, y, width, height); if (SUCCEEDED(result)) { return result; } } } } return EELEMENTNOTDISPLAYED; } long top = 0, bottom = 0, left = 0, right = 0; rect->get_top(&top); rect->get_left(&left); rect->get_bottom(&bottom); rect->get_right(&right); long w = right - left; long h = bottom - top; if (!hasAbsolutePositionReadyToReturn) { // On versions of IE prior to 8 on Vista, if the element is out of the // viewport this would seem to return 0,0,0,0. IE 8 returns position in // the DOM regardless of whether it's in the browser viewport. long scroll_left, scroll_top = 0; element2->get_scrollLeft(&scroll_left); element2->get_scrollTop(&scroll_top); left += scroll_left; top += scroll_top; long frame_offset_x = 0, frame_offset_y = 0; this->GetFrameOffset(&frame_offset_x, &frame_offset_y); left += frame_offset_x; top += frame_offset_y; } *x = left; *y = top; *width = w; *height = h; return SUCCESS; }