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

    if (node->hasTagName(HTMLNames::areaTag)) {
        HTMLAreaElement* area = static_cast<HTMLAreaElement*>(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);
}
Esempio n. 2
0
// This method filters what element will get tap-highlight'ed or not. To start with,
// we are going to highlight links (anchors with a valid href element), and elements
// whose tap highlight color value is different than the default value.
static Element* elementForTapHighlight(Element* elementUnderFatFinger)
{
    // Do not bail out right way here if there element does not have a renderer.
    // It is the casefor <map> (descendent of <area>) elements. The associated <image>
    // element actually has the renderer.
    if (elementUnderFatFinger->renderer()) {
        Color tapHighlightColor = elementUnderFatFinger->renderStyle()->tapHighlightColor();
        if (tapHighlightColor != RenderTheme::defaultTheme()->platformTapHighlightColor())
            return elementUnderFatFinger;
    }

    bool isArea = elementUnderFatFinger->hasTagName(HTMLNames::areaTag);
    Node* linkNode = elementUnderFatFinger->enclosingLinkEventParentOrSelf();
    if (!linkNode || !linkNode->isHTMLElement() || (!linkNode->renderer() && !isArea))
        return 0;

    ASSERT(linkNode->isLink());

    // FatFingers class selector ensure only anchor with valid href attr value get here.
    // It includes empty hrefs.
    Element* highlightCandidateElement = static_cast<Element*>(linkNode);

    if (!isArea)
        return highlightCandidateElement;

    HTMLAreaElement* area = static_cast<HTMLAreaElement*>(highlightCandidateElement);
    HTMLImageElement* image = area->imageElement();
    if (image && image->renderer())
        return image;

    return 0;
}
Esempio n. 3
0
LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement& area, FocusType type)
{
    ASSERT(area.imageElement());
    // Area elements tend to overlap more than other focusable elements. We flatten the rect of the area elements
    // to minimize the effect of overlapping areas.
    LayoutRect rect = virtualRectForDirection(type, rectToAbsoluteCoordinates(area.document().frame(), area.computeRect(area.imageElement()->renderer())), 1);
    return rect;
}
void RenderImage::paintAreaElementFocusRing(PaintInfo& paintInfo)
{
    Document* document = this->document();

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

    if (paintInfo.context->paintingDisabled() && !paintInfo.context->updatingControlTints())
        return;

    Element* focusedElement = document->focusedElement();
    if (!focusedElement || !isHTMLAreaElement(focusedElement))
        return;

    HTMLAreaElement* areaElement = toHTMLAreaElement(focusedElement);
    if (areaElement->imageElement() != 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(this);
    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(absoluteContentBox());
    paintInfo.context->drawFocusRing(path, outlineWidth,
        areaElementStyle->outlineOffset(),
        resolveColor(areaElementStyle, CSSPropertyOutlineColor));
}
Esempio n. 5
0
void RenderImage::paintAreaElementFocusRing(PaintInfo& paintInfo)
{
    Document* document = this->document();
    
    if (document->printing() || !document->frame()->selection()->isFocusedAndActive())
        return;
    
    if (paintInfo.context->paintingDisabled() && !paintInfo.context->updatingControlTints())
        return;

    Node* focusedNode = document->focusedNode();
    if (!focusedNode || !focusedNode->hasTagName(areaTag))
        return;

    HTMLAreaElement* areaElement = static_cast<HTMLAreaElement*>(focusedNode);
    if (areaElement->imageElement() != 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(this);
    if (path.isEmpty())
        return;

    // FIXME: Do we need additional code to clip the path to the image's bounding box?

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

    paintInfo.context->drawFocusRing(path, outlineWidth,
        areaElementStyle->outlineOffset(),
        areaElementStyle->visitedDependentColor(CSSPropertyOutlineColor));
}
Esempio n. 6
0
bool FocusController::advanceFocusDirectionally(FocusDirection direction, KeyboardEvent* event)
{
    Frame* curFrame = focusedOrMainFrame();
    ASSERT(curFrame);

    Document* focusedDocument = curFrame->document();
    if (!focusedDocument)
        return false;

    Node* focusedNode = focusedDocument->focusedNode();
    Node* container = focusedDocument;

    if (container->isDocumentNode())
        static_cast<Document*>(container)->updateLayoutIgnorePendingStylesheets();
        
    // Figure out the starting rect.
    LayoutRect startingRect;
    if (focusedNode) {
        if (!hasOffscreenRect(focusedNode)) {
            container = scrollableEnclosingBoxOrParentFrameForNodeInDirection(direction, focusedNode);
            startingRect = nodeRectInAbsoluteCoordinates(focusedNode, true /* ignore border */);
        } else if (focusedNode->hasTagName(areaTag)) {
            HTMLAreaElement* area = static_cast<HTMLAreaElement*>(focusedNode);
            container = scrollableEnclosingBoxOrParentFrameForNodeInDirection(direction, area->imageElement());
            startingRect = virtualRectForAreaElementAndDirection(area, direction);
        }
    }

    bool consumed = false;
    do {
        consumed = advanceFocusDirectionallyInContainer(container, startingRect, direction, event);
        startingRect = nodeRectInAbsoluteCoordinates(container, true /* ignore border */);
        container = scrollableEnclosingBoxOrParentFrameForNodeInDirection(direction, container);
        if (container && container->isDocumentNode())
            static_cast<Document*>(container)->updateLayoutIgnorePendingStylesheets();
    } while (!consumed && container);

    return consumed;
}
Esempio n. 7
0
void RenderImage::readyWRATHWidgetAreaElementFocusRing(PaintedWidgetsOfWRATHHandle& handle, PaintInfoOfWRATH& paintInfo)
{
    RenderImage_ReadyWRATHWidgetAreaElementFocusRing *d(RenderImage_ReadyWRATHWidgetAreaElementFocusRing::object(this, handle));
    ContextOfWRATH::AutoPushNode autoPushRoot(paintInfo.wrath_context, d->m_root_node);

    if (d->m_focus_ring.widget())
        d->m_focus_ring.widget()->visible(false);

    Document* document = this->document();

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

    /*
    if (paintInfo.context->paintingDisabled() && !paintInfo.context->updatingControlTints())
        return;
    */

    Node* focusedNode = document->focusedNode();
    if (!focusedNode || !focusedNode->hasTagName(areaTag))
        return;

    HTMLAreaElement* areaElement = static_cast<HTMLAreaElement*>(focusedNode);
    if (areaElement->imageElement() != 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(this);
    if (path.isEmpty())
        return;

    // FIXME: Do we need additional code to clip the path to the image's bounding box?

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

    if (!d->m_focus_ring_shape || d->m_focus_ring_dirty) {
        if (!d->m_focus_ring_shape) {
            d->m_focus_ring_shape = WRATHNew WRATHShapeF;
        }

        d->m_focus_ring_shape->clear();
        d->m_focus_ring_shape->new_outline();

        QPainterPath qpath = path.platformPath();

        // Skip the first element, it is not needed because it's the same as the last
        for (int i = 1; i < qpath.elementCount(); ++i) {
            const QPainterPath::Element & cur = qpath.elementAt(i);

            switch (cur.type) {
            case QPainterPath::MoveToElement: {
                ASSERT_NOT_REACHED();
                break;
            }
            case QPainterPath::LineToElement: {
                QPointF p(cur);
                d->m_focus_ring_shape->current_outline() << vec2(p.x(), p.y());
                break;
            }
            case QPainterPath::CurveToElement: {
                QPainterPath::Element c1 = qpath.elementAt(i+1);
                QPainterPath::Element c2 = qpath.elementAt(i+2);

                ASSERT(c1.type == QPainterPath::CurveToDataElement);
                ASSERT(c2.type == QPainterPath::CurveToDataElement);

                QPointF p1(cur);
                QPointF p2(c1);
                QPointF p3(c2);

                d->m_focus_ring_shape->current_outline() <<
                        WRATHOutlineF::control_point(vec2(p1.x(), p1.y())) <<
                        WRATHOutlineF::control_point(vec2(p2.x(), p2.y())) <<
                        vec2(p3.x(), p3.y());

                i += 2;

                break;
            }
            case QPainterPath::CurveToDataElement: {
                ASSERT_NOT_REACHED();
                break;
            }
            }
        }
    }

    vec4 c;
    Color wc = areaElementStyle->visitedDependentColor(CSSPropertyOutlineColor);
    wc.getRGBA(c.x(), c.y(), c.z(), c.w());

    paintInfo.wrath_context->add_stroked_shape(d->m_focus_ring,
            WRATHWidgetGenerator::ColorProperties(c),
            WRATHWidgetGenerator::shape_value(*d->m_focus_ring_shape),
            WRATHWidgetGenerator::StrokingParameters()
            .close_outline(true)
            .width(outlineWidth)
            .stroke_curves(WRATHWidgetGenerator::dashed_stroke));
    d->m_focus_ring.widget()->visible(true);
}