FocusCandidate::FocusCandidate(Node* node, FocusDirection direction)
    : visibleNode(0)
    , focusableNode(0)
    , enclosingScrollableBox(0)
    , distance(maxDistance())
    , alignment(None)
    , isOffscreen(true)
    , isOffscreenAfterScrolling(true)
{
    ASSERT(node);
    ASSERT(node->isElementNode());

    if (isHTMLAreaElement(node)) {
        HTMLAreaElement* area = toHTMLAreaElement(node);
        HTMLImageElement* image = area->imageElement();
        if (!image || !image->renderer())
            return;

        visibleNode = image;
        rect = virtualRectForAreaElementAndDirection(area, direction);
    } else {
        if (!node->renderer())
            return;

        visibleNode = node;
        rect = nodeRectInAbsoluteCoordinates(node, true /* ignore border */);
    }

    focusableNode = node;
    isOffscreen = hasOffscreenRect(visibleNode);
    isOffscreenAfterScrolling = hasOffscreenRect(visibleNode, direction);
}
Beispiel #2
0
void ImagePainter::paintAreaElementFocusRing(PaintInfo& paintInfo)
{
    Document& document = m_renderImage.document();

    if (document.printing() || !document.frame()->selection().isFocusedAndActive())
        return;

    Element* focusedElement = document.focusedElement();
    if (!isHTMLAreaElement(focusedElement))
        return;

    HTMLAreaElement& areaElement = toHTMLAreaElement(*focusedElement);
    if (areaElement.imageElement() != m_renderImage.node())
        return;

    // Even if the theme handles focus ring drawing for entire elements, it won't do it for
    // an area within an image, so we don't call RenderTheme::supportsFocusRing here.

    Path path = areaElement.computePath(&m_renderImage);
    if (path.isEmpty())
        return;

    RenderStyle* areaElementStyle = areaElement.computedStyle();
    unsigned short outlineWidth = areaElementStyle->outlineWidth();
    if (!outlineWidth)
        return;

    // FIXME: Clip path instead of context when Skia pathops is ready.
    // https://crbug.com/251206
    GraphicsContextStateSaver savedContext(*paintInfo.context);
    paintInfo.context->clip(m_renderImage.absoluteContentBox());
    paintInfo.context->drawFocusRing(path, outlineWidth,
                                     areaElementStyle->outlineOffset(),
                                     m_renderImage.resolveColor(areaElementStyle, CSSPropertyOutlineColor));
}
Beispiel #3
0
void ImagePainter::paintAreaElementFocusRing(const PaintInfo& paintInfo,
                                             const LayoutPoint& paintOffset) {
  Document& document = m_layoutImage.document();

  if (paintInfo.isPrinting() ||
      !document.frame()->selection().isFocusedAndActive())
    return;

  Element* focusedElement = document.focusedElement();
  if (!isHTMLAreaElement(focusedElement))
    return;

  HTMLAreaElement& areaElement = toHTMLAreaElement(*focusedElement);
  if (areaElement.imageElement() != m_layoutImage.node())
    return;

  // Even if the theme handles focus ring drawing for entire elements, it won't
  // do it for an area within an image, so we don't call
  // LayoutTheme::themeDrawsFocusRing here.

  const ComputedStyle& areaElementStyle = *areaElement.ensureComputedStyle();
  // If the outline width is 0 we want to avoid drawing anything even if we
  // don't use the value directly.
  if (!areaElementStyle.outlineWidth())
    return;

  Path path = areaElement.getPath(&m_layoutImage);
  if (path.isEmpty())
    return;

  LayoutPoint adjustedPaintOffset = paintOffset;
  adjustedPaintOffset.moveBy(m_layoutImage.location());
  path.translate(FloatSize(adjustedPaintOffset.x(), adjustedPaintOffset.y()));

  if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(
          paintInfo.context, m_layoutImage, DisplayItem::kImageAreaFocusRing))
    return;

  LayoutRect focusRect = m_layoutImage.contentBoxRect();
  focusRect.moveBy(adjustedPaintOffset);
  LayoutObjectDrawingRecorder drawingRecorder(paintInfo.context, m_layoutImage,
                                              DisplayItem::kImageAreaFocusRing,
                                              focusRect);

  // FIXME: Clip path instead of context when Skia pathops is ready.
  // https://crbug.com/251206

  paintInfo.context.save();
  paintInfo.context.clip(pixelSnappedIntRect(focusRect));
  paintInfo.context.drawFocusRing(
      path, areaElementStyle.getOutlineStrokeWidthForFocusRing(),
      areaElementStyle.outlineOffset(),
      m_layoutImage.resolveColor(areaElementStyle, CSSPropertyOutlineColor));
  paintInfo.context.restore();
}
bool areElementsOnSameLine(const FocusCandidate& firstCandidate, const FocusCandidate& secondCandidate)
{
    if (firstCandidate.isNull() || secondCandidate.isNull())
        return false;

    if (!firstCandidate.visibleNode->renderer() || !secondCandidate.visibleNode->renderer())
        return false;

    if (!firstCandidate.rect.intersects(secondCandidate.rect))
        return false;

    if (isHTMLAreaElement(firstCandidate.focusableNode) || isHTMLAreaElement(secondCandidate.focusableNode))
        return false;

    if (!firstCandidate.visibleNode->renderer()->isRenderInline() || !secondCandidate.visibleNode->renderer()->isRenderInline())
        return false;

    if (firstCandidate.visibleNode->renderer()->containingBlock() != secondCandidate.visibleNode->renderer()->containingBlock())
        return false;

    return true;
}
Beispiel #5
0
void ImagePainter::paintAreaElementFocusRing(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
    // TODO(wangxianzhu): In other places, we just paint focus ring if outline style is auto.
    // We should also do that here to keep consistency.
    Document& document = m_layoutImage.document();

    if (paintInfo.isPrinting() || !document.frame()->selection().isFocusedAndActive())
        return;

    Element* focusedElement = document.focusedElement();
    if (!isHTMLAreaElement(focusedElement))
        return;

    HTMLAreaElement& areaElement = toHTMLAreaElement(*focusedElement);
    if (areaElement.imageElement() != m_layoutImage.node())
        return;

    // Even if the theme handles focus ring drawing for entire elements, it won't do it for
    // an area within an image, so we don't call LayoutTheme::themeDrawsFocusRing here.

    Path path = areaElement.computePath(&m_layoutImage);
    if (path.isEmpty())
        return;

    const ComputedStyle& areaElementStyle = *areaElement.ensureComputedStyle();
    int outlineWidth = areaElementStyle.outlineWidth();
    if (!outlineWidth)
        return;

    if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(*paintInfo.context, m_layoutImage, paintInfo.phase, paintOffset))
        return;

    IntRect focusRect = m_layoutImage.absoluteContentBox();
    LayoutObjectDrawingRecorder drawingRecorder(*paintInfo.context, m_layoutImage, paintInfo.phase, focusRect, paintOffset);

    // FIXME: Clip path instead of context when Skia pathops is ready.
    // https://crbug.com/251206

    paintInfo.context->save();
    paintInfo.context->clip(focusRect);
    paintInfo.context->drawFocusRing(path, outlineWidth,
                                     areaElementStyle.outlineOffset(),
                                     m_layoutImage.resolveColor(areaElementStyle, CSSPropertyOutlineColor));
    paintInfo.context->restore();
}
Beispiel #6
0
bool elementHasLegalLinkAttribute(const Element* element, const QualifiedName& attrName)
{
    if (attrName == srcAttr)
        return element->hasTagName(imgTag) || element->hasTagName(scriptTag) || element->hasTagName(iframeTag) || element->hasTagName(frameTag) || (element->hasTagName(inputTag) && toHTMLInputElement(element)->isImageButton());
    if (attrName == hrefAttr)
        return element->hasTagName(linkTag) || isHTMLAnchorElement(element) || isHTMLAreaElement(element);
    if (attrName == actionAttr)
        return element->hasTagName(formTag);
    if (attrName == backgroundAttr)
        return element->hasTagName(bodyTag) || isHTMLTableElement(element) || element->hasTagName(trTag) || element->hasTagName(tdTag);
    if (attrName == citeAttr)
        return element->hasTagName(blockquoteTag) || element->hasTagName(qTag) || element->hasTagName(delTag) || element->hasTagName(insTag);
    if (attrName == classidAttr || attrName == dataAttr)
        return element->hasTagName(objectTag);
    if (attrName == codebaseAttr)
        return element->hasTagName(objectTag) || element->hasTagName(appletTag);
    return false;
}
Beispiel #7
0
void ImagePainter::paintAreaElementFocusRing(const PaintInfo& paintInfo)
{
    Document& document = m_layoutImage.document();

    if (document.printing() || !document.frame()->selection().isFocusedAndActive())
        return;

    Element* focusedElement = document.focusedElement();
    if (!isHTMLAreaElement(focusedElement))
        return;

    HTMLAreaElement& areaElement = toHTMLAreaElement(*focusedElement);
    if (areaElement.imageElement() != m_layoutImage.node())
        return;

    // Even if the theme handles focus ring drawing for entire elements, it won't do it for
    // an area within an image, so we don't call LayoutTheme::supportsFocusRing here.

    Path path = areaElement.computePath(&m_layoutImage);
    if (path.isEmpty())
        return;

    const ComputedStyle& areaElementStyle = *areaElement.ensureComputedStyle();
    unsigned short outlineWidth = areaElementStyle.outlineWidth();
    if (!outlineWidth)
        return;

    IntRect focusRect = m_layoutImage.absoluteContentBox();

    LayoutObjectDrawingRecorder drawingRecorder(*paintInfo.context, m_layoutImage, paintInfo.phase, focusRect);
    if (drawingRecorder.canUseCachedDrawing())
        return;

    // FIXME: Clip path instead of context when Skia pathops is ready.
    // https://crbug.com/251206

    paintInfo.context->save();
    paintInfo.context->clip(focusRect);
    paintInfo.context->drawFocusRing(path, outlineWidth,
        areaElementStyle.outlineOffset(),
        m_layoutImage.resolveColor(areaElementStyle, CSSPropertyOutlineColor));
    paintInfo.context->restore();
}