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); }
static v8::Handle<v8::Value> searchAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { INC_STATS("DOM.HTMLAreaElement.search._get"); HTMLAreaElement* imp = V8HTMLAreaElement::toNative(info.Holder()); if (!R_check(imp)) return v8::Handle<v8::Value>(v8::Undefined()); return v8String(imp->search()); }
static v8::Handle<v8::Value> noHrefAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { INC_STATS("DOM.HTMLAreaElement.noHref._get"); HTMLAreaElement* imp = V8HTMLAreaElement::toNative(info.Holder()); if (!R_check(imp)) return v8::Handle<v8::Value>(v8::Undefined()); return v8Boolean(imp->hasAttribute(WebCore::HTMLNames::nohrefAttr)); }
static void noHrefAttrSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) { INC_STATS("DOM.HTMLAreaElement.noHref._set"); HTMLAreaElement* imp = V8HTMLAreaElement::toNative(info.Holder()); bool v = value->BooleanValue(); imp->setNoHref(v); return; }
// 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; }
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; }
bool HTMLMapElement::mapMouseEvent(LayoutPoint location, const LayoutSize& size, HitTestResult& result) { HTMLAreaElement* defaultArea = 0; for (HTMLAreaElement* area = Traversal<HTMLAreaElement>::firstWithin(*this); area; area = Traversal<HTMLAreaElement>::next(*area, this)) { if (area->isDefault()) { if (!defaultArea) defaultArea = area; } else if (area->mapMouseEvent(location, size, result)) { return true; } } if (defaultArea) { result.setInnerNode(defaultArea); result.setURLElement(defaultArea); } return defaultArea; }
bool HTMLMapElement::mapMouseEvent(LayoutPoint location, const LayoutSize& size, HitTestResult& result) { HTMLAreaElement* defaultArea = 0; Element* element = this; while ((element = ElementTraversal::next(element, this))) { if (element->hasTagName(areaTag)) { HTMLAreaElement* areaElt = static_cast<HTMLAreaElement*>(element); if (areaElt->isDefault()) { if (!defaultArea) defaultArea = areaElt; } else if (areaElt->mapMouseEvent(location, size, result)) return true; } } if (defaultArea) { result.setInnerNode(defaultArea); result.setURLElement(defaultArea); } return defaultArea; }
bool HTMLMapElement::mapMouseEvent(int x, int y, const IntSize& size, HitTestResult& result) { HTMLAreaElement* defaultArea = 0; Node *node = this; while ((node = node->traverseNextNode(this))) { if (node->hasTagName(areaTag)) { HTMLAreaElement* areaElt = static_cast<HTMLAreaElement*>(node); if (areaElt->isDefault()) { if (!defaultArea) defaultArea = areaElt; } else if (areaElt->mapMouseEvent(x, y, size, result)) return true; } } if (defaultArea) { result.setInnerNode(defaultArea); result.setURLElement(defaultArea); } return defaultArea; }
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)); }
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)); }
void RenderImage::paintFocusRings(PaintInfo& paintInfo, const RenderStyle* style) { // Don't draw focus rings if printing. if (document()->printing() || !document()->frame()->selection()->isFocusedAndActive()) return; if (paintInfo.context->paintingDisabled() && !paintInfo.context->updatingControlTints()) return; HTMLMapElement* mapElement = imageMap(); if (!mapElement) return; Document* document = mapElement->document(); if (!document) return; Node* focusedNode = document->focusedNode(); if (!focusedNode) return; RefPtr<HTMLCollection> areas = mapElement->areas(); unsigned numAreas = areas->length(); // FIXME: Clip the paths to the image bounding box. for (unsigned k = 0; k < numAreas; ++k) { HTMLAreaElement* areaElement = static_cast<HTMLAreaElement*>(areas->item(k)); if (focusedNode != areaElement) continue; Vector<Path> focusRingPaths; focusRingPaths.append(areaElement->getPath(this)); paintInfo.context->drawFocusRing(focusRingPaths, style->outlineWidth(), style->outlineOffset(), style->outlineColor()); break; } }
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; }
static v8::Handle<v8::Value> hrefAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { INC_STATS("DOM.HTMLAreaElement.href._get"); HTMLAreaElement* imp = V8HTMLAreaElement::toNative(info.Holder()); return v8String(imp->getURLAttribute(WebCore::HTMLNames::hrefAttr)); }
static v8::Handle<v8::Value> noHrefAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { INC_STATS("DOM.HTMLAreaElement.noHref._get"); HTMLAreaElement* imp = V8HTMLAreaElement::toNative(info.Holder()); return v8Boolean(imp->noHref()); }
static v8::Handle<v8::Value> protocolAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { INC_STATS("DOM.HTMLAreaElement.protocol._get"); HTMLAreaElement* imp = V8HTMLAreaElement::toNative(info.Holder()); return v8String(imp->protocol()); }
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); }