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); }
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)); }
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; }
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(); }
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; }
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(); }