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;
}
Example #2
0
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);
		}
	}
}
Example #3
0
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;
}
Example #4
0
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;
}